1
17 package org.apache.catalina.connector;
18
19 import java.io.BufferedReader;
20 import java.io.File;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.StringReader;
24 import java.io.UnsupportedEncodingException;
25 import java.nio.charset.Charset;
26 import java.nio.charset.StandardCharsets;
27 import java.security.Principal;
28 import java.text.SimpleDateFormat;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.Enumeration;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.List;
36 import java.util.Locale;
37 import java.util.Map;
38 import java.util.Set;
39 import java.util.TimeZone;
40 import java.util.TreeMap;
41 import java.util.concurrent.ConcurrentHashMap;
42 import java.util.concurrent.atomic.AtomicBoolean;
43
44 import javax.naming.NamingException;
45 import javax.security.auth.Subject;
46 import javax.servlet.AsyncContext;
47 import javax.servlet.DispatcherType;
48 import javax.servlet.FilterChain;
49 import javax.servlet.MultipartConfigElement;
50 import javax.servlet.RequestDispatcher;
51 import javax.servlet.ServletContext;
52 import javax.servlet.ServletException;
53 import javax.servlet.ServletInputStream;
54 import javax.servlet.ServletRequest;
55 import javax.servlet.ServletRequestAttributeEvent;
56 import javax.servlet.ServletRequestAttributeListener;
57 import javax.servlet.ServletResponse;
58 import javax.servlet.SessionTrackingMode;
59 import javax.servlet.http.Cookie;
60 import javax.servlet.http.HttpServletMapping;
61 import javax.servlet.http.HttpServletRequest;
62 import javax.servlet.http.HttpServletRequestWrapper;
63 import javax.servlet.http.HttpServletResponse;
64 import javax.servlet.http.HttpSession;
65 import javax.servlet.http.HttpUpgradeHandler;
66 import javax.servlet.http.Part;
67 import javax.servlet.http.PushBuilder;
68
69 import org.apache.catalina.Container;
70 import org.apache.catalina.Context;
71 import org.apache.catalina.Globals;
72 import org.apache.catalina.Host;
73 import org.apache.catalina.Manager;
74 import org.apache.catalina.Realm;
75 import org.apache.catalina.Session;
76 import org.apache.catalina.TomcatPrincipal;
77 import org.apache.catalina.Wrapper;
78 import org.apache.catalina.core.ApplicationFilterChain;
79 import org.apache.catalina.core.ApplicationMapping;
80 import org.apache.catalina.core.ApplicationPart;
81 import org.apache.catalina.core.ApplicationPushBuilder;
82 import org.apache.catalina.core.ApplicationSessionCookieConfig;
83 import org.apache.catalina.core.AsyncContextImpl;
84 import org.apache.catalina.mapper.MappingData;
85 import org.apache.catalina.util.ParameterMap;
86 import org.apache.catalina.util.RequestUtil;
87 import org.apache.catalina.util.TLSUtil;
88 import org.apache.catalina.util.URLEncoder;
89 import org.apache.coyote.ActionCode;
90 import org.apache.coyote.UpgradeToken;
91 import org.apache.coyote.http11.upgrade.InternalHttpUpgradeHandler;
92 import org.apache.juli.logging.Log;
93 import org.apache.juli.logging.LogFactory;
94 import org.apache.tomcat.InstanceManager;
95 import org.apache.tomcat.util.ExceptionUtils;
96 import org.apache.tomcat.util.buf.B2CConverter;
97 import org.apache.tomcat.util.buf.ByteChunk;
98 import org.apache.tomcat.util.buf.MessageBytes;
99 import org.apache.tomcat.util.buf.StringUtils;
100 import org.apache.tomcat.util.buf.UDecoder;
101 import org.apache.tomcat.util.http.CookieProcessor;
102 import org.apache.tomcat.util.http.FastHttpDateFormat;
103 import org.apache.tomcat.util.http.Parameters;
104 import org.apache.tomcat.util.http.Parameters.FailReason;
105 import org.apache.tomcat.util.http.ServerCookie;
106 import org.apache.tomcat.util.http.ServerCookies;
107 import org.apache.tomcat.util.http.fileupload.FileItem;
108 import org.apache.tomcat.util.http.fileupload.FileUploadException;
109 import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
110 import org.apache.tomcat.util.http.fileupload.impl.InvalidContentTypeException;
111 import org.apache.tomcat.util.http.fileupload.impl.SizeException;
112 import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
113 import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext;
114 import org.apache.tomcat.util.http.parser.AcceptLanguage;
115 import org.apache.tomcat.util.net.SSLSupport;
116 import org.apache.tomcat.util.res.StringManager;
117 import org.ietf.jgss.GSSCredential;
118 import org.ietf.jgss.GSSException;
119
120
126 public class Request implements HttpServletRequest {
127
128 private static final Log log = LogFactory.getLog(Request.class);
129
130
138 public Request(Connector connector) {
139 this.connector = connector;
140
141 formats = new SimpleDateFormat[formatsTemplate.length];
142 for(int i = 0; i < formats.length; i++) {
143 formats[i] = (SimpleDateFormat) formatsTemplate[i].clone();
144 }
145 }
146
147
148
149
150
151
154 protected org.apache.coyote.Request coyoteRequest;
155
156
161 public void setCoyoteRequest(org.apache.coyote.Request coyoteRequest) {
162 this.coyoteRequest = coyoteRequest;
163 inputBuffer.setRequest(coyoteRequest);
164 }
165
166
171 public org.apache.coyote.Request getCoyoteRequest() {
172 return this.coyoteRequest;
173 }
174
175
176
177
178
181 @Deprecated
182 protected static final TimeZone GMT_ZONE = TimeZone.getTimeZone("GMT");
183
184
185
188 protected static final StringManager sm = StringManager.getManager(Request.class);
189
190
191
194 protected Cookie[] cookies = null;
195
196
197
205 @Deprecated
206 protected final SimpleDateFormat formats[];
207
208 @Deprecated
209 private static final SimpleDateFormat formatsTemplate[] = {
210 new SimpleDateFormat(FastHttpDateFormat.RFC1123_DATE, Locale.US),
211 new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
212 new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)
213 };
214
215
216
219 protected static final Locale defaultLocale = Locale.getDefault();
220
221
222
225 private final Map<String, Object> attributes = new ConcurrentHashMap<>();
226
227
228
233 protected boolean sslAttributesParsed = false;
234
235
236
239 protected final ArrayList<Locale> locales = new ArrayList<>();
240
241
242
246 private final transient HashMap<String, Object> notes = new HashMap<>();
247
248
249
252 protected String authType = null;
253
254
255
258 protected DispatcherType internalDispatcherType = null;
259
260
261
264 protected final InputBuffer inputBuffer = new InputBuffer();
265
266
267
270 protected CoyoteInputStream inputStream =
271 new CoyoteInputStream(inputBuffer);
272
273
274
277 protected CoyoteReader reader = new CoyoteReader(inputBuffer);
278
279
280
283 protected boolean usingInputStream = false;
284
285
286
289 protected boolean usingReader = false;
290
291
292
295 protected Principal userPrincipal = null;
296
297
298
301 protected boolean parametersParsed = false;
302
303
304
308 protected boolean cookiesParsed = false;
309
310
311
315 protected boolean cookiesConverted = false;
316
317
318
321 protected boolean secure = false;
322
323
324
327 protected transient Subject subject = null;
328
329
330
333 protected static final int CACHED_POST_LEN = 8192;
334 protected byte[] postData = null;
335
336
337
340 protected ParameterMap<String, String[]> parameterMap = new ParameterMap<>();
341
342
343
346 protected Collection<Part> parts = null;
347
348
349
352 protected Exception partsParseException = null;
353
354
355
358 protected Session session = null;
359
360
361
364 protected Object requestDispatcherPath = null;
365
366
367
370 protected boolean requestedSessionCookie = false;
371
372
373
376 protected String requestedSessionId = null;
377
378
379
382 protected boolean requestedSessionURL = false;
383
384
385
388 protected boolean requestedSessionSSL = false;
389
390
391
394 protected boolean localesParsed = false;
395
396
397
400 protected int localPort = -1;
401
402
405 protected String remoteAddr = null;
406
407
408
411 protected String remoteHost = null;
412
413
414
417 protected int remotePort = -1;
418
419
422 protected String localAddr = null;
423
424
425
428 protected String localName = null;
429
430
433 private volatile AsyncContextImpl asyncContext = null;
434
435 protected Boolean asyncSupported = null;
436
437 private HttpServletRequest applicationRequest = null;
438
439
440
441
442 protected void addPathParameter(String name, String value) {
443 coyoteRequest.addPathParameter(name, value);
444 }
445
446 protected String getPathParameter(String name) {
447 return coyoteRequest.getPathParameter(name);
448 }
449
450 public void setAsyncSupported(boolean asyncSupported) {
451 this.asyncSupported = Boolean.valueOf(asyncSupported);
452 }
453
454
458 public void recycle() {
459
460 internalDispatcherType = null;
461 requestDispatcherPath = null;
462
463 authType = null;
464 inputBuffer.recycle();
465 usingInputStream = false;
466 usingReader = false;
467 userPrincipal = null;
468 subject = null;
469 parametersParsed = false;
470 if (parts != null) {
471 for (Part part: parts) {
472 try {
473 part.delete();
474 } catch (IOException ignored) {
475
476 }
477 }
478 parts = null;
479 }
480 partsParseException = null;
481 locales.clear();
482 localesParsed = false;
483 secure = false;
484 remoteAddr = null;
485 remoteHost = null;
486 remotePort = -1;
487 localPort = -1;
488 localAddr = null;
489 localName = null;
490
491 attributes.clear();
492 sslAttributesParsed = false;
493 notes.clear();
494
495 recycleSessionInfo();
496 recycleCookieInfo(false);
497
498 if (getDiscardFacades()) {
499 parameterMap = new ParameterMap<>();
500 } else {
501 parameterMap.setLocked(false);
502 parameterMap.clear();
503 }
504
505 mappingData.recycle();
506 applicationMapping.recycle();
507
508 applicationRequest = null;
509 if (getDiscardFacades()) {
510 if (facade != null) {
511 facade.clear();
512 facade = null;
513 }
514 if (inputStream != null) {
515 inputStream.clear();
516 inputStream = null;
517 }
518 if (reader != null) {
519 reader.clear();
520 reader = null;
521 }
522 }
523
524 asyncSupported = null;
525 if (asyncContext!=null) {
526 asyncContext.recycle();
527 }
528 asyncContext = null;
529 }
530
531
532 protected void recycleSessionInfo() {
533 if (session != null) {
534 try {
535 session.endAccess();
536 } catch (Throwable t) {
537 ExceptionUtils.handleThrowable(t);
538 log.warn(sm.getString("coyoteRequest.sessionEndAccessFail"), t);
539 }
540 }
541 session = null;
542 requestedSessionCookie = false;
543 requestedSessionId = null;
544 requestedSessionURL = false;
545 requestedSessionSSL = false;
546 }
547
548
549 protected void recycleCookieInfo(boolean recycleCoyote) {
550 cookiesParsed = false;
551 cookiesConverted = false;
552 cookies = null;
553 if (recycleCoyote) {
554 getCoyoteRequest().getCookies().recycle();
555 }
556 }
557
558
559
560
561
564 protected final Connector connector;
565
566
569 public Connector getConnector() {
570 return this.connector;
571 }
572
573
574
583 public Context getContext() {
584 return mappingData.context;
585 }
586
587
588
593 public boolean getDiscardFacades() {
594 return (connector == null) ? true : connector.getDiscardFacades();
595 }
596
597
598
601 protected FilterChain filterChain = null;
602
603
608 public FilterChain getFilterChain() {
609 return this.filterChain;
610 }
611
612
617 public void setFilterChain(FilterChain filterChain) {
618 this.filterChain = filterChain;
619 }
620
621
622
625 public Host getHost() {
626 return mappingData.host;
627 }
628
629
630
633 protected final MappingData mappingData = new MappingData();
634 private final ApplicationMapping applicationMapping = new ApplicationMapping(mappingData);
635
636
639 public MappingData getMappingData() {
640 return mappingData;
641 }
642
643
644
647 protected RequestFacade facade = null;
648
649
650
654 public HttpServletRequest getRequest() {
655 if (facade == null) {
656 facade = new RequestFacade(this);
657 }
658 if (applicationRequest == null) {
659 applicationRequest = facade;
660 }
661 return applicationRequest;
662 }
663
664
665
673 public void setRequest(HttpServletRequest applicationRequest) {
674
675 ServletRequest r = applicationRequest;
676 while (r instanceof HttpServletRequestWrapper) {
677 r = ((HttpServletRequestWrapper) r).getRequest();
678 }
679 if (r != facade) {
680 throw new IllegalArgumentException(sm.getString("request.illegalWrap"));
681 }
682 this.applicationRequest = applicationRequest;
683 }
684
685
686
689 protected org.apache.catalina.connector.Response response = null;
690
691
694 public org.apache.catalina.connector.Response getResponse() {
695 return this.response;
696 }
697
698
703 public void setResponse(org.apache.catalina.connector.Response response) {
704 this.response = response;
705 }
706
707
710 public InputStream getStream() {
711 if (inputStream == null) {
712 inputStream = new CoyoteInputStream(inputBuffer);
713 }
714 return inputStream;
715 }
716
717
720 protected B2CConverter URIConverter = null;
721
722
725 protected B2CConverter getURIConverter() {
726 return URIConverter;
727 }
728
729
734 protected void setURIConverter(B2CConverter URIConverter) {
735 this.URIConverter = URIConverter;
736 }
737
738
739
742 public Wrapper getWrapper() {
743 return mappingData.wrapper;
744 }
745
746
747
748
749
756 public ServletInputStream createInputStream()
757 throws IOException {
758 if (inputStream == null) {
759 inputStream = new CoyoteInputStream(inputBuffer);
760 }
761 return inputStream;
762 }
763
764
765
771 public void finishRequest() throws IOException {
772 if (response.getStatus() == HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE) {
773 checkSwallowInput();
774 }
775 }
776
777
778
784 public Object getNote(String name) {
785 return notes.get(name);
786 }
787
788
789
795 public void removeNote(String name) {
796 notes.remove(name);
797 }
798
799
800
805 public void setLocalPort(int port) {
806 localPort = port;
807 }
808
809
816 public void setNote(String name, Object value) {
817 notes.put(name, value);
818 }
819
820
821
826 public void setRemoteAddr(String remoteAddr) {
827 this.remoteAddr = remoteAddr;
828 }
829
830
831
837 public void setRemoteHost(String remoteHost) {
838 this.remoteHost = remoteHost;
839 }
840
841
842
848 public void setSecure(boolean secure) {
849 this.secure = secure;
850 }
851
852
853
858 public void setServerPort(int port) {
859 coyoteRequest.setServerPort(port);
860 }
861
862
863
864
865
871 @Override
872 public Object getAttribute(String name) {
873
874 SpecialAttributeAdapter adapter = specialAttributes.get(name);
875 if (adapter != null) {
876 return adapter.get(this, name);
877 }
878
879 Object attr = attributes.get(name);
880
881 if (attr != null) {
882 return attr;
883 }
884
885 attr = coyoteRequest.getAttribute(name);
886 if (attr != null) {
887 return attr;
888 }
889 if (TLSUtil.isTLSRequestAttribute(name)) {
890 coyoteRequest.action(ActionCode.REQ_SSL_ATTRIBUTE, coyoteRequest);
891 attr = coyoteRequest.getAttribute(Globals.CERTIFICATES_ATTR);
892 if (attr != null) {
893 attributes.put(Globals.CERTIFICATES_ATTR, attr);
894 }
895 attr = coyoteRequest.getAttribute(Globals.CIPHER_SUITE_ATTR);
896 if (attr != null) {
897 attributes.put(Globals.CIPHER_SUITE_ATTR, attr);
898 }
899 attr = coyoteRequest.getAttribute(Globals.KEY_SIZE_ATTR);
900 if (attr != null) {
901 attributes.put(Globals.KEY_SIZE_ATTR, attr);
902 }
903 attr = coyoteRequest.getAttribute(Globals.SSL_SESSION_ID_ATTR);
904 if (attr != null) {
905 attributes.put(Globals.SSL_SESSION_ID_ATTR, attr);
906 }
907 attr = coyoteRequest.getAttribute(Globals.SSL_SESSION_MGR_ATTR);
908 if (attr != null) {
909 attributes.put(Globals.SSL_SESSION_MGR_ATTR, attr);
910 }
911 attr = coyoteRequest.getAttribute(SSLSupport.PROTOCOL_VERSION_KEY);
912 if (attr != null) {
913 attributes.put(SSLSupport.PROTOCOL_VERSION_KEY, attr);
914 }
915 attr = attributes.get(name);
916 sslAttributesParsed = true;
917 }
918 return attr;
919 }
920
921
922 @Override
923 public long getContentLengthLong() {
924 return coyoteRequest.getContentLengthLong();
925 }
926
927
928
956 @Override
957 public Enumeration<String> getAttributeNames() {
958 if (isSecure() && !sslAttributesParsed) {
959 getAttribute(Globals.CERTIFICATES_ATTR);
960 }
961
962
963 Set<String> names = new HashSet<>();
964 names.addAll(attributes.keySet());
965 return Collections.enumeration(names);
966 }
967
968
969
972 @Override
973 public String getCharacterEncoding() {
974 String characterEncoding = coyoteRequest.getCharacterEncoding();
975 if (characterEncoding != null) {
976 return characterEncoding;
977 }
978
979 Context context = getContext();
980 if (context != null) {
981 return context.getRequestCharacterEncoding();
982 }
983
984 return null;
985 }
986
987
988 private Charset getCharset() {
989 Charset charset = null;
990 try {
991 charset = coyoteRequest.getCharset();
992 } catch (UnsupportedEncodingException e) {
993
994 }
995 if (charset != null) {
996 return charset;
997 }
998
999 Context context = getContext();
1000 if (context != null) {
1001 String encoding = context.getRequestCharacterEncoding();
1002 if (encoding != null) {
1003 try {
1004 return B2CConverter.getCharset(encoding);
1005 } catch (UnsupportedEncodingException e) {
1006
1007 }
1008 }
1009 }
1010
1011 return org.apache.coyote.Constants.DEFAULT_BODY_CHARSET;
1012 }
1013
1014
1015
1018 @Override
1019 public int getContentLength() {
1020 return coyoteRequest.getContentLength();
1021 }
1022
1023
1024
1027 @Override
1028 public String getContentType() {
1029 return coyoteRequest.getContentType();
1030 }
1031
1032
1033
1038 public void setContentType(String contentType) {
1039 coyoteRequest.setContentType(contentType);
1040 }
1041
1042
1043
1052 @Override
1053 public ServletInputStream getInputStream() throws IOException {
1054
1055 if (usingReader) {
1056 throw new IllegalStateException(sm.getString("coyoteRequest.getInputStream.ise"));
1057 }
1058
1059 usingInputStream = true;
1060 if (inputStream == null) {
1061 inputStream = new CoyoteInputStream(inputBuffer);
1062 }
1063 return inputStream;
1064
1065 }
1066
1067
1068
1074 @Override
1075 public Locale getLocale() {
1076
1077 if (!localesParsed) {
1078 parseLocales();
1079 }
1080
1081 if (locales.size() > 0) {
1082 return locales.get(0);
1083 }
1084
1085 return defaultLocale;
1086 }
1087
1088
1089
1095 @Override
1096 public Enumeration<Locale> getLocales() {
1097
1098 if (!localesParsed) {
1099 parseLocales();
1100 }
1101
1102 if (locales.size() > 0) {
1103 return Collections.enumeration(locales);
1104 }
1105 ArrayList<Locale> results = new ArrayList<>();
1106 results.add(defaultLocale);
1107 return Collections.enumeration(results);
1108
1109 }
1110
1111
1112
1119 @Override
1120 public String getParameter(String name) {
1121
1122 if (!parametersParsed) {
1123 parseParameters();
1124 }
1125
1126 return coyoteRequest.getParameters().getParameter(name);
1127
1128 }
1129
1130
1131
1132
1141 @Override
1142 public Map<String, String[]> getParameterMap() {
1143
1144 if (parameterMap.isLocked()) {
1145 return parameterMap;
1146 }
1147
1148 Enumeration<String> enumeration = getParameterNames();
1149 while (enumeration.hasMoreElements()) {
1150 String name = enumeration.nextElement();
1151 String[] values = getParameterValues(name);
1152 parameterMap.put(name, values);
1153 }
1154
1155 parameterMap.setLocked(true);
1156
1157 return parameterMap;
1158
1159 }
1160
1161
1162
1165 @Override
1166 public Enumeration<String> getParameterNames() {
1167
1168 if (!parametersParsed) {
1169 parseParameters();
1170 }
1171
1172 return coyoteRequest.getParameters().getParameterNames();
1173
1174 }
1175
1176
1177
1183 @Override
1184 public String[] getParameterValues(String name) {
1185
1186 if (!parametersParsed) {
1187 parseParameters();
1188 }
1189
1190 return coyoteRequest.getParameters().getParameterValues(name);
1191
1192 }
1193
1194
1195
1198 @Override
1199 public String getProtocol() {
1200 return coyoteRequest.protocol().toString();
1201 }
1202
1203
1204
1214 @Override
1215 public BufferedReader getReader() throws IOException {
1216
1217 if (usingInputStream) {
1218 throw new IllegalStateException(sm.getString("coyoteRequest.getReader.ise"));
1219 }
1220
1221
1222
1223
1224
1225 if (coyoteRequest.getCharacterEncoding() == null) {
1226
1227
1228 Context context = getContext();
1229 if (context != null) {
1230 String enc = context.getRequestCharacterEncoding();
1231 if (enc != null) {
1232
1233
1234 setCharacterEncoding(enc);
1235 }
1236 }
1237 }
1238
1239 usingReader = true;
1240
1241 inputBuffer.checkConverter();
1242 if (reader == null) {
1243 reader = new CoyoteReader(inputBuffer);
1244 }
1245 return reader;
1246 }
1247
1248
1249
1257 @Override
1258 @Deprecated
1259 public String getRealPath(String path) {
1260
1261 Context context = getContext();
1262 if (context == null) {
1263 return null;
1264 }
1265 ServletContext servletContext = context.getServletContext();
1266 if (servletContext == null) {
1267 return null;
1268 }
1269
1270 try {
1271 return servletContext.getRealPath(path);
1272 } catch (IllegalArgumentException e) {
1273 return null;
1274 }
1275 }
1276
1277
1278
1281 @Override
1282 public String getRemoteAddr() {
1283 if (remoteAddr == null) {
1284 coyoteRequest.action(ActionCode.REQ_HOST_ADDR_ATTRIBUTE, coyoteRequest);
1285 remoteAddr = coyoteRequest.remoteAddr().toString();
1286 }
1287 return remoteAddr;
1288 }
1289
1290
1291
1294 @Override
1295 public String getRemoteHost() {
1296 if (remoteHost == null) {
1297 if (!connector.getEnableLookups()) {
1298 remoteHost = getRemoteAddr();
1299 } else {
1300 coyoteRequest.action(ActionCode.REQ_HOST_ATTRIBUTE, coyoteRequest);
1301 remoteHost = coyoteRequest.remoteHost().toString();
1302 }
1303 }
1304 return remoteHost;
1305 }
1306
1307
1311 @Override
1312 public int getRemotePort(){
1313 if (remotePort == -1) {
1314 coyoteRequest.action(ActionCode.REQ_REMOTEPORT_ATTRIBUTE, coyoteRequest);
1315 remotePort = coyoteRequest.getRemotePort();
1316 }
1317 return remotePort;
1318 }
1319
1320
1324 @Override
1325 public String getLocalName(){
1326 if (localName == null) {
1327 coyoteRequest.action(ActionCode.REQ_LOCAL_NAME_ATTRIBUTE, coyoteRequest);
1328 localName = coyoteRequest.localName().toString();
1329 }
1330 return localName;
1331 }
1332
1333
1337 @Override
1338 public String getLocalAddr(){
1339 if (localAddr == null) {
1340 coyoteRequest.action(ActionCode.REQ_LOCAL_ADDR_ATTRIBUTE, coyoteRequest);
1341 localAddr = coyoteRequest.localAddr().toString();
1342 }
1343 return localAddr;
1344 }
1345
1346
1347
1351 @Override
1352 public int getLocalPort(){
1353 if (localPort == -1){
1354 coyoteRequest.action(ActionCode.REQ_LOCALPORT_ATTRIBUTE, coyoteRequest);
1355 localPort = coyoteRequest.getLocalPort();
1356 }
1357 return localPort;
1358 }
1359
1360
1366 @Override
1367 public RequestDispatcher getRequestDispatcher(String path) {
1368
1369 Context context = getContext();
1370 if (context == null) {
1371 return null;
1372 }
1373
1374 if (path == null) {
1375 return null;
1376 }
1377
1378 int fragmentPos = path.indexOf('#');
1379 if (fragmentPos > -1) {
1380 log.warn(sm.getString("request.fragmentInDispatchPath", path));
1381 path = path.substring(0, fragmentPos);
1382 }
1383
1384
1385 if (path.startsWith("/")) {
1386 return context.getServletContext().getRequestDispatcher(path);
1387 }
1388
1389
1407
1408
1409 String servletPath = (String) getAttribute(
1410 RequestDispatcher.INCLUDE_SERVLET_PATH);
1411 if (servletPath == null) {
1412 servletPath = getServletPath();
1413 }
1414
1415
1416 String pathInfo = getPathInfo();
1417 String requestPath = null;
1418
1419 if (pathInfo == null) {
1420 requestPath = servletPath;
1421 } else {
1422 requestPath = servletPath + pathInfo;
1423 }
1424
1425 int pos = requestPath.lastIndexOf('/');
1426 String relative = null;
1427 if (context.getDispatchersUseEncodedPaths()) {
1428 if (pos >= 0) {
1429 relative = URLEncoder.DEFAULT.encode(
1430 requestPath.substring(0, pos + 1), StandardCharsets.UTF_8) + path;
1431 } else {
1432 relative = URLEncoder.DEFAULT.encode(requestPath, StandardCharsets.UTF_8) + path;
1433 }
1434 } else {
1435 if (pos >= 0) {
1436 relative = requestPath.substring(0, pos + 1) + path;
1437 } else {
1438 relative = requestPath + path;
1439 }
1440 }
1441
1442 return context.getServletContext().getRequestDispatcher(relative);
1443 }
1444
1445
1446
1449 @Override
1450 public String getScheme() {
1451 return coyoteRequest.scheme().toString();
1452 }
1453
1454
1455
1458 @Override
1459 public String getServerName() {
1460 return coyoteRequest.serverName().toString();
1461 }
1462
1463
1464
1467 @Override
1468 public int getServerPort() {
1469 return coyoteRequest.getServerPort();
1470 }
1471
1472
1473
1476 @Override
1477 public boolean isSecure() {
1478 return secure;
1479 }
1480
1481
1482
1487 @Override
1488 public void removeAttribute(String name) {
1489
1490
1491 if (name.startsWith("org.apache.tomcat.")) {
1492 coyoteRequest.getAttributes().remove(name);
1493 }
1494
1495 boolean found = attributes.containsKey(name);
1496 if (found) {
1497 Object value = attributes.get(name);
1498 attributes.remove(name);
1499
1500
1501 notifyAttributeRemoved(name, value);
1502 }
1503 }
1504
1505
1506
1512 @Override
1513 public void setAttribute(String name, Object value) {
1514
1515
1516 if (name == null) {
1517 throw new IllegalArgumentException(sm.getString("coyoteRequest.setAttribute.namenull"));
1518 }
1519
1520
1521 if (value == null) {
1522 removeAttribute(name);
1523 return;
1524 }
1525
1526
1527 SpecialAttributeAdapter adapter = specialAttributes.get(name);
1528 if (adapter != null) {
1529 adapter.set(this, name, value);
1530 return;
1531 }
1532
1533
1534
1535 if (Globals.IS_SECURITY_ENABLED &&
1536 name.equals(Globals.SENDFILE_FILENAME_ATTR)) {
1537
1538
1539 String canonicalPath;
1540 try {
1541 canonicalPath = new File(value.toString()).getCanonicalPath();
1542 } catch (IOException e) {
1543 throw new SecurityException(sm.getString(
1544 "coyoteRequest.sendfileNotCanonical", value), e);
1545 }
1546
1547
1548
1549 System.getSecurityManager().checkRead(canonicalPath);
1550
1551 value = canonicalPath;
1552 }
1553
1554 Object oldValue = attributes.put(name, value);
1555
1556
1557 if (name.startsWith("org.apache.tomcat.")) {
1558 coyoteRequest.setAttribute(name, value);
1559 }
1560
1561
1562 notifyAttributeAssigned(name, value, oldValue);
1563 }
1564
1565
1566
1573 private void notifyAttributeAssigned(String name, Object value,
1574 Object oldValue) {
1575 Context context = getContext();
1576 if (context == null) {
1577 return;
1578 }
1579 Object listeners[] = context.getApplicationEventListeners();
1580 if ((listeners == null) || (listeners.length == 0)) {
1581 return;
1582 }
1583 boolean replaced = (oldValue != null);
1584 ServletRequestAttributeEvent event = null;
1585 if (replaced) {
1586 event = new ServletRequestAttributeEvent(
1587 context.getServletContext(), getRequest(), name, oldValue);
1588 } else {
1589 event = new ServletRequestAttributeEvent(
1590 context.getServletContext(), getRequest(), name, value);
1591 }
1592
1593 for (int i = 0; i < listeners.length; i++) {
1594 if (!(listeners[i] instanceof ServletRequestAttributeListener)) {
1595 continue;
1596 }
1597 ServletRequestAttributeListener listener =
1598 (ServletRequestAttributeListener) listeners[i];
1599 try {
1600 if (replaced) {
1601 listener.attributeReplaced(event);
1602 } else {
1603 listener.attributeAdded(event);
1604 }
1605 } catch (Throwable t) {
1606 ExceptionUtils.handleThrowable(t);
1607
1608 attributes.put(RequestDispatcher.ERROR_EXCEPTION, t);
1609 context.getLogger().error(sm.getString("coyoteRequest.attributeEvent"), t);
1610 }
1611 }
1612 }
1613
1614
1615
1621 private void notifyAttributeRemoved(String name, Object value) {
1622 Context context = getContext();
1623 Object listeners[] = context.getApplicationEventListeners();
1624 if ((listeners == null) || (listeners.length == 0)) {
1625 return;
1626 }
1627 ServletRequestAttributeEvent event =
1628 new ServletRequestAttributeEvent(context.getServletContext(),
1629 getRequest(), name, value);
1630 for (int i = 0; i < listeners.length; i++) {
1631 if (!(listeners[i] instanceof ServletRequestAttributeListener)) {
1632 continue;
1633 }
1634 ServletRequestAttributeListener listener =
1635 (ServletRequestAttributeListener) listeners[i];
1636 try {
1637 listener.attributeRemoved(event);
1638 } catch (Throwable t) {
1639 ExceptionUtils.handleThrowable(t);
1640
1641 attributes.put(RequestDispatcher.ERROR_EXCEPTION, t);
1642 context.getLogger().error(sm.getString("coyoteRequest.attributeEvent"), t);
1643 }
1644 }
1645 }
1646
1647
1648
1660 @Override
1661 public void setCharacterEncoding(String enc) throws UnsupportedEncodingException {
1662
1663 if (usingReader) {
1664 return;
1665 }
1666
1667
1668 Charset charset = B2CConverter.getCharset(enc);
1669
1670
1671 coyoteRequest.setCharset(charset);
1672 }
1673
1674
1675 @Override
1676 public ServletContext getServletContext() {
1677 return getContext().getServletContext();
1678 }
1679
1680 @Override
1681 public AsyncContext startAsync() {
1682 return startAsync(getRequest(),response.getResponse());
1683 }
1684
1685 @Override
1686 public AsyncContext startAsync(ServletRequest request,
1687 ServletResponse response) {
1688 if (!isAsyncSupported()) {
1689 IllegalStateException ise =
1690 new IllegalStateException(sm.getString("request.asyncNotSupported"));
1691 log.warn(sm.getString("coyoteRequest.noAsync",
1692 StringUtils.join(getNonAsyncClassNames())), ise);
1693 throw ise;
1694 }
1695
1696 if (asyncContext == null) {
1697 asyncContext = new AsyncContextImpl(this);
1698 }
1699
1700 asyncContext.setStarted(getContext(), request, response,
1701 request==getRequest() && response==getResponse().getResponse());
1702 asyncContext.setTimeout(getConnector().getAsyncTimeout());
1703
1704 return asyncContext;
1705 }
1706
1707
1708 private Set<String> getNonAsyncClassNames() {
1709 Set<String> result = new HashSet<>();
1710
1711 Wrapper wrapper = getWrapper();
1712 if (!wrapper.isAsyncSupported()) {
1713 result.add(wrapper.getServletClass());
1714 }
1715
1716 FilterChain filterChain = getFilterChain();
1717 if (filterChain instanceof ApplicationFilterChain) {
1718 ((ApplicationFilterChain) filterChain).findNonAsyncFilters(result);
1719 } else {
1720 result.add(sm.getString("coyoteRequest.filterAsyncSupportUnknown"));
1721 }
1722
1723 Container c = wrapper;
1724 while (c != null) {
1725 c.getPipeline().findNonAsyncValves(result);
1726 c = c.getParent();
1727 }
1728
1729 return result;
1730 }
1731
1732 @Override
1733 public boolean isAsyncStarted() {
1734 if (asyncContext == null) {
1735 return false;
1736 }
1737
1738 return asyncContext.isStarted();
1739 }
1740
1741 public boolean isAsyncDispatching() {
1742 if (asyncContext == null) {
1743 return false;
1744 }
1745
1746 AtomicBoolean result = new AtomicBoolean(false);
1747 coyoteRequest.action(ActionCode.ASYNC_IS_DISPATCHING, result);
1748 return result.get();
1749 }
1750
1751 public boolean isAsyncCompleting() {
1752 if (asyncContext == null) {
1753 return false;
1754 }
1755
1756 AtomicBoolean result = new AtomicBoolean(false);
1757 coyoteRequest.action(ActionCode.ASYNC_IS_COMPLETING, result);
1758 return result.get();
1759 }
1760
1761 public boolean isAsync() {
1762 if (asyncContext == null) {
1763 return false;
1764 }
1765
1766 AtomicBoolean result = new AtomicBoolean(false);
1767 coyoteRequest.action(ActionCode.ASYNC_IS_ASYNC, result);
1768 return result.get();
1769 }
1770
1771 @Override
1772 public boolean isAsyncSupported() {
1773 if (this.asyncSupported == null) {
1774 return true;
1775 }
1776
1777 return asyncSupported.booleanValue();
1778 }
1779
1780 @Override
1781 public AsyncContext getAsyncContext() {
1782 if (!isAsyncStarted()) {
1783 throw new IllegalStateException(sm.getString("request.notAsync"));
1784 }
1785 return asyncContext;
1786 }
1787
1788 public AsyncContextImpl getAsyncContextInternal() {
1789 return asyncContext;
1790 }
1791
1792 @Override
1793 public DispatcherType getDispatcherType() {
1794 if (internalDispatcherType == null) {
1795 return DispatcherType.REQUEST;
1796 }
1797
1798 return this.internalDispatcherType;
1799 }
1800
1801
1802
1803
1804
1809 public void addCookie(Cookie cookie) {
1810
1811 if (!cookiesConverted) {
1812 convertCookies();
1813 }
1814
1815 int size = 0;
1816 if (cookies != null) {
1817 size = cookies.length;
1818 }
1819
1820 Cookie[] newCookies = new Cookie[size + 1];
1821 if (cookies != null) {
1822 System.arraycopy(cookies, 0, newCookies, 0, size);
1823 }
1824 newCookies[size] = cookie;
1825
1826 cookies = newCookies;
1827
1828 }
1829
1830
1831
1837 public void addLocale(Locale locale) {
1838 locales.add(locale);
1839 }
1840
1841
1842
1845 public void clearCookies() {
1846 cookiesParsed = true;
1847 cookiesConverted = true;
1848 cookies = null;
1849 }
1850
1851
1852
1855 public void clearLocales() {
1856 locales.clear();
1857 }
1858
1859
1860
1867 public void setAuthType(String type) {
1868 this.authType = type;
1869 }
1870
1871
1872
1879 public void setPathInfo(String path) {
1880 mappingData.pathInfo.setString(path);
1881 }
1882
1883
1884
1891 public void setRequestedSessionCookie(boolean flag) {
1892
1893 this.requestedSessionCookie = flag;
1894
1895 }
1896
1897
1898
1904 public void setRequestedSessionId(String id) {
1905
1906 this.requestedSessionId = id;
1907
1908 }
1909
1910
1911
1918 public void setRequestedSessionURL(boolean flag) {
1919
1920 this.requestedSessionURL = flag;
1921
1922 }
1923
1924
1925
1932 public void setRequestedSessionSSL(boolean flag) {
1933
1934 this.requestedSessionSSL = flag;
1935
1936 }
1937
1938
1939
1944 public String getDecodedRequestURI() {
1945 return coyoteRequest.decodedURI().toString();
1946 }
1947
1948
1949
1954 public MessageBytes getDecodedRequestURIMB() {
1955 return coyoteRequest.decodedURI();
1956 }
1957
1958
1959
1966 public void setUserPrincipal(final Principal principal) {
1967 if (Globals.IS_SECURITY_ENABLED && principal != null) {
1968 if (subject == null) {
1969 final HttpSession session = getSession(false);
1970 if (session == null) {
1971
1972 subject = newSubject(principal);
1973 } else {
1974
1975 subject = (Subject) session.getAttribute(Globals.SUBJECT_ATTR);
1976 if (subject == null) {
1977 subject = newSubject(principal);
1978 session.setAttribute(Globals.SUBJECT_ATTR, subject);
1979 } else {
1980 subject.getPrincipals().add(principal);
1981 }
1982 }
1983 } else {
1984 subject.getPrincipals().add(principal);
1985 }
1986 }
1987 userPrincipal = principal;
1988 }
1989
1990
1991 private Subject newSubject(final Principal principal) {
1992 final Subject result = new Subject();
1993 result.getPrincipals().add(principal);
1994 return result;
1995 }
1996
1997
1998
1999
2000 @Override
2001 public boolean isTrailerFieldsReady() {
2002 return coyoteRequest.isTrailerFieldsReady();
2003 }
2004
2005
2006 @Override
2007 public Map<String, String> getTrailerFields() {
2008 if (!isTrailerFieldsReady()) {
2009 throw new IllegalStateException(sm.getString("coyoteRequest.trailersNotReady"));
2010 }
2011 Map<String,String> result = new HashMap<>();
2012 result.putAll(coyoteRequest.getTrailerFields());
2013 return result;
2014 }
2015
2016
2017 @Override
2018 public PushBuilder newPushBuilder() {
2019 return newPushBuilder(this);
2020 }
2021
2022
2023 public PushBuilder newPushBuilder(HttpServletRequest request) {
2024 AtomicBoolean result = new AtomicBoolean();
2025 coyoteRequest.action(ActionCode.IS_PUSH_SUPPORTED, result);
2026 if (result.get()) {
2027 return new ApplicationPushBuilder(this, request);
2028 } else {
2029 return null;
2030 }
2031 }
2032
2033
2034 @SuppressWarnings("unchecked")
2035 @Override
2036 public <T extends HttpUpgradeHandler> T upgrade(
2037 Class<T> httpUpgradeHandlerClass) throws java.io.IOException, ServletException {
2038 T handler;
2039 InstanceManager instanceManager = null;
2040 try {
2041
2042
2043 if (InternalHttpUpgradeHandler.class.isAssignableFrom(httpUpgradeHandlerClass)) {
2044 handler = httpUpgradeHandlerClass.getConstructor().newInstance();
2045 } else {
2046 instanceManager = getContext().getInstanceManager();
2047 handler = (T) instanceManager.newInstance(httpUpgradeHandlerClass);
2048 }
2049 } catch (ReflectiveOperationException | NamingException | IllegalArgumentException |
2050 SecurityException e) {
2051 throw new ServletException(e);
2052 }
2053 UpgradeToken upgradeToken = new UpgradeToken(handler,
2054 getContext(), instanceManager);
2055
2056 coyoteRequest.action(ActionCode.UPGRADE, upgradeToken);
2057
2058
2059
2060 response.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS);
2061
2062 return handler;
2063 }
2064
2065
2068 @Override
2069 public String getAuthType() {
2070 return authType;
2071 }
2072
2073
2074
2079 @Override
2080 public String getContextPath() {
2081 int lastSlash = mappingData.contextSlashCount;
2082
2083 if (lastSlash == 0) {
2084 return "";
2085 }
2086
2087 String canonicalContextPath = getServletContext().getContextPath();
2088
2089 String uri = getRequestURI();
2090 int pos = 0;
2091 if (!getContext().getAllowMultipleLeadingForwardSlashInPath()) {
2092
2093
2094
2095 do {
2096 pos++;
2097 } while (pos < uri.length() && uri.charAt(pos) == '/');
2098 pos--;
2099 uri = uri.substring(pos);
2100 }
2101
2102 char[] uriChars = uri.toCharArray();
2103
2104 while (lastSlash > 0) {
2105 pos = nextSlash(uriChars, pos + 1);
2106 if (pos == -1) {
2107 break;
2108 }
2109 lastSlash--;
2110 }
2111
2112
2113
2114
2115 String candidate;
2116 if (pos == -1) {
2117 candidate = uri;
2118 } else {
2119 candidate = uri.substring(0, pos);
2120 }
2121 candidate = removePathParameters(candidate);
2122 candidate = UDecoder.URLDecode(candidate, connector.getURICharset());
2123 candidate = org.apache.tomcat.util.http.RequestUtil.normalize(candidate);
2124 boolean match = canonicalContextPath.equals(candidate);
2125 while (!match && pos != -1) {
2126 pos = nextSlash(uriChars, pos + 1);
2127 if (pos == -1) {
2128 candidate = uri;
2129 } else {
2130 candidate = uri.substring(0, pos);
2131 }
2132 candidate = removePathParameters(candidate);
2133 candidate = UDecoder.URLDecode(candidate, connector.getURICharset());
2134 candidate = org.apache.tomcat.util.http.RequestUtil.normalize(candidate);
2135 match = canonicalContextPath.equals(candidate);
2136 }
2137 if (match) {
2138 if (pos == -1) {
2139 return uri;
2140 } else {
2141 return uri.substring(0, pos);
2142 }
2143 } else {
2144
2145 throw new IllegalStateException(sm.getString(
2146 "coyoteRequest.getContextPath.ise", canonicalContextPath, uri));
2147 }
2148 }
2149
2150
2151 private String removePathParameters(String input) {
2152 int nextSemiColon = input.indexOf(';');
2153
2154 if (nextSemiColon == -1) {
2155 return input;
2156 }
2157 StringBuilder result = new StringBuilder(input.length());
2158 result.append(input.substring(0, nextSemiColon));
2159 while (true) {
2160 int nextSlash = input.indexOf('/', nextSemiColon);
2161 if (nextSlash == -1) {
2162 break;
2163 }
2164 nextSemiColon = input.indexOf(';', nextSlash);
2165 if (nextSemiColon == -1) {
2166 result.append(input.substring(nextSlash));
2167 break;
2168 } else {
2169 result.append(input.substring(nextSlash, nextSemiColon));
2170 }
2171 }
2172
2173 return result.toString();
2174 }
2175
2176
2177 private int nextSlash(char[] uri, int startPos) {
2178 int len = uri.length;
2179 int pos = startPos;
2180 while (pos < len) {
2181 if (uri[pos] == '/') {
2182 return pos;
2183 } else if (UDecoder.ALLOW_ENCODED_SLASH && uri[pos] == '%' && pos + 2 < len &&
2184 uri[pos+1] == '2' && (uri[pos + 2] == 'f' || uri[pos + 2] == 'F')) {
2185 return pos;
2186 }
2187 pos++;
2188 }
2189 return -1;
2190 }
2191
2192
2193
2200 @Override
2201 public Cookie[] getCookies() {
2202 if (!cookiesConverted) {
2203 convertCookies();
2204 }
2205 return cookies;
2206 }
2207
2208
2209
2216 public ServerCookies getServerCookies() {
2217 parseCookies();
2218 return coyoteRequest.getCookies();
2219 }
2220
2221
2222
2232 @Override
2233 public long getDateHeader(String name) {
2234
2235 String value = getHeader(name);
2236 if (value == null) {
2237 return -1L;
2238 }
2239
2240
2241 long result = FastHttpDateFormat.parseDate(value);
2242 if (result != (-1L)) {
2243 return result;
2244 }
2245 throw new IllegalArgumentException(value);
2246
2247 }
2248
2249
2250
2257 @Override
2258 public String getHeader(String name) {
2259 return coyoteRequest.getHeader(name);
2260 }
2261
2262
2263
2270 @Override
2271 public Enumeration<String> getHeaders(String name) {
2272 return coyoteRequest.getMimeHeaders().values(name);
2273 }
2274
2275
2276
2279 @Override
2280 public Enumeration<String> getHeaderNames() {
2281 return coyoteRequest.getMimeHeaders().names();
2282 }
2283
2284
2285
2295 @Override
2296 public int getIntHeader(String name) {
2297
2298 String value = getHeader(name);
2299 if (value == null) {
2300 return -1;
2301 }
2302
2303 return Integer.parseInt(value);
2304 }
2305
2306
2307 @Override
2308 public HttpServletMapping getHttpServletMapping() {
2309 return applicationMapping.getHttpServletMapping();
2310 }
2311
2312
2313
2316 @Override
2317 public String getMethod() {
2318 return coyoteRequest.method().toString();
2319 }
2320
2321
2322
2325 @Override
2326 public String getPathInfo() {
2327 return mappingData.pathInfo.toString();
2328 }
2329
2330
2331
2335 @Override
2336 public String getPathTranslated() {
2337
2338 Context context = getContext();
2339 if (context == null) {
2340 return null;
2341 }
2342
2343 if (getPathInfo() == null) {
2344 return null;
2345 }
2346
2347 return context.getServletContext().getRealPath(getPathInfo());
2348 }
2349
2350
2351
2354 @Override
2355 public String getQueryString() {
2356 return coyoteRequest.queryString().toString();
2357 }
2358
2359
2360
2364 @Override
2365 public String getRemoteUser() {
2366
2367 if (userPrincipal == null) {
2368 return null;
2369 }
2370
2371 return userPrincipal.getName();
2372 }
2373
2374
2375
2380 public MessageBytes getRequestPathMB() {
2381 return mappingData.requestPath;
2382 }
2383
2384
2385
2388 @Override
2389 public String getRequestedSessionId() {
2390 return requestedSessionId;
2391 }
2392
2393
2394
2397 @Override
2398 public String getRequestURI() {
2399 return coyoteRequest.requestURI().toString();
2400 }
2401
2402
2403 @Override
2404 public StringBuffer getRequestURL() {
2405 return RequestUtil.getRequestURL(this);
2406 }
2407
2408
2409
2413 @Override
2414 public String getServletPath() {
2415 return mappingData.wrapperPath.toString();
2416 }
2417
2418
2419
2423 @Override
2424 public HttpSession getSession() {
2425 Session session = doGetSession(true);
2426 if (session == null) {
2427 return null;
2428 }
2429
2430 return session.getSession();
2431 }
2432
2433
2434
2440 @Override
2441 public HttpSession getSession(boolean create) {
2442 Session session = doGetSession(create);
2443 if (session == null) {
2444 return null;
2445 }
2446
2447 return session.getSession();
2448 }
2449
2450
2451
2455 @Override
2456 public boolean isRequestedSessionIdFromCookie() {
2457
2458 if (requestedSessionId == null) {
2459 return false;
2460 }
2461
2462 return requestedSessionCookie;
2463 }
2464
2465
2466
2470 @Override
2471 public boolean isRequestedSessionIdFromURL() {
2472
2473 if (requestedSessionId == null) {
2474 return false;
2475 }
2476
2477 return requestedSessionURL;
2478 }
2479
2480
2481
2488 @Override
2489 @Deprecated
2490 public boolean isRequestedSessionIdFromUrl() {
2491 return isRequestedSessionIdFromURL();
2492 }
2493
2494
2495
2499 @Override
2500 public boolean isRequestedSessionIdValid() {
2501
2502 if (requestedSessionId == null) {
2503 return false;
2504 }
2505
2506 Context context = getContext();
2507 if (context == null) {
2508 return false;
2509 }
2510
2511 Manager manager = context.getManager();
2512 if (manager == null) {
2513 return false;
2514 }
2515
2516 Session session = null;
2517 try {
2518 session = manager.findSession(requestedSessionId);
2519 } catch (IOException e) {
2520
2521 }
2522
2523 if ((session == null) || !session.isValid()) {
2524
2525 if (getMappingData().contexts == null) {
2526 return false;
2527 } else {
2528 for (int i = (getMappingData().contexts.length); i > 0; i--) {
2529 Context ctxt = getMappingData().contexts[i - 1];
2530 try {
2531 if (ctxt.getManager().findSession(requestedSessionId) !=
2532 null) {
2533 return true;
2534 }
2535 } catch (IOException e) {
2536
2537 }
2538 }
2539 return false;
2540 }
2541 }
2542
2543 return true;
2544 }
2545
2546
2547
2553 @Override
2554 public boolean isUserInRole(String role) {
2555
2556
2557 if (userPrincipal == null) {
2558 return false;
2559 }
2560
2561
2562 Context context = getContext();
2563 if (context == null) {
2564 return false;
2565 }
2566
2567
2568
2569 if ("*".equals(role)) {
2570 return false;
2571 }
2572
2573
2574
2575 if ("**".equals(role) && !context.findSecurityRole("**")) {
2576 return userPrincipal != null;
2577 }
2578
2579 Realm realm = context.getRealm();
2580 if (realm == null) {
2581 return false;
2582 }
2583
2584
2585 return realm.hasRole(getWrapper(), userPrincipal, role);
2586 }
2587
2588
2589
2592 public Principal getPrincipal() {
2593 return userPrincipal;
2594 }
2595
2596
2597
2600 @Override
2601 public Principal getUserPrincipal() {
2602 if (userPrincipal instanceof TomcatPrincipal) {
2603 GSSCredential gssCredential =
2604 ((TomcatPrincipal) userPrincipal).getGssCredential();
2605 if (gssCredential != null) {
2606 int left = -1;
2607 try {
2608 left = gssCredential.getRemainingLifetime();
2609 } catch (GSSException e) {
2610 log.warn(sm.getString("coyoteRequest.gssLifetimeFail",
2611 userPrincipal.getName()), e);
2612 }
2613 if (left == 0) {
2614
2615 try {
2616 logout();
2617 } catch (ServletException e) {
2618
2619
2620 }
2621 return null;
2622 }
2623 }
2624 return ((TomcatPrincipal) userPrincipal).getUserPrincipal();
2625 }
2626
2627 return userPrincipal;
2628 }
2629
2630
2631
2635 public Session getSessionInternal() {
2636 return doGetSession(true);
2637 }
2638
2639
2640
2648 public void changeSessionId(String newSessionId) {
2649
2650
2651 if (requestedSessionId != null && requestedSessionId.length() > 0) {
2652 requestedSessionId = newSessionId;
2653 }
2654
2655 Context context = getContext();
2656 if (context != null &&
2657 !context.getServletContext()
2658 .getEffectiveSessionTrackingModes()
2659 .contains(SessionTrackingMode.COOKIE)) {
2660 return;
2661 }
2662
2663 if (response != null) {
2664 Cookie newCookie = ApplicationSessionCookieConfig.createSessionCookie(context,
2665 newSessionId, isSecure());
2666 response.addSessionCookieInternal(newCookie);
2667 }
2668 }
2669
2670
2671 @Override
2672 public String changeSessionId() {
2673
2674 Session session = this.getSessionInternal(false);
2675 if (session == null) {
2676 throw new IllegalStateException(
2677 sm.getString("coyoteRequest.changeSessionId"));
2678 }
2679
2680 Manager manager = this.getContext().getManager();
2681
2682 String newSessionId = manager.rotateSessionId(session);
2683 this.changeSessionId(newSessionId);
2684
2685 return newSessionId;
2686 }
2687
2688
2694 public Session getSessionInternal(boolean create) {
2695 return doGetSession(create);
2696 }
2697
2698
2699
2702 public boolean isParametersParsed() {
2703 return parametersParsed;
2704 }
2705
2706
2707
2711 public boolean isFinished() {
2712 return coyoteRequest.isFinished();
2713 }
2714
2715
2716
2721 protected void checkSwallowInput() {
2722 Context context = getContext();
2723 if (context != null && !context.getSwallowAbortedUploads()) {
2724 coyoteRequest.action(ActionCode.DISABLE_SWALLOW_INPUT, null);
2725 }
2726 }
2727
2728
2731 @Override
2732 public boolean authenticate(HttpServletResponse response)
2733 throws IOException, ServletException {
2734 if (response.isCommitted()) {
2735 throw new IllegalStateException(
2736 sm.getString("coyoteRequest.authenticate.ise"));
2737 }
2738
2739 return getContext().getAuthenticator().authenticate(this, response);
2740 }
2741
2742
2745 @Override
2746 public void login(String username, String password)
2747 throws ServletException {
2748 if (getAuthType() != null || getRemoteUser() != null ||
2749 getUserPrincipal() != null) {
2750 throw new ServletException(
2751 sm.getString("coyoteRequest.alreadyAuthenticated"));
2752 }
2753
2754 getContext().getAuthenticator().login(username, password, this);
2755 }
2756
2757
2760 @Override
2761 public void logout() throws ServletException {
2762 getContext().getAuthenticator().logout(this);
2763 }
2764
2765
2768 @Override
2769 public Collection<Part> getParts() throws IOException, IllegalStateException,
2770 ServletException {
2771
2772 parseParts(true);
2773
2774 if (partsParseException != null) {
2775 if (partsParseException instanceof IOException) {
2776 throw (IOException) partsParseException;
2777 } else if (partsParseException instanceof IllegalStateException) {
2778 throw (IllegalStateException) partsParseException;
2779 } else if (partsParseException instanceof ServletException) {
2780 throw (ServletException) partsParseException;
2781 }
2782 }
2783
2784 return parts;
2785 }
2786
2787 private void parseParts(boolean explicit) {
2788
2789
2790 if (parts != null || partsParseException != null) {
2791 return;
2792 }
2793
2794 Context context = getContext();
2795 MultipartConfigElement mce = getWrapper().getMultipartConfigElement();
2796
2797 if (mce == null) {
2798 if(context.getAllowCasualMultipartParsing()) {
2799 mce = new MultipartConfigElement(null, connector.getMaxPostSize(),
2800 connector.getMaxPostSize(), connector.getMaxPostSize());
2801 } else {
2802 if (explicit) {
2803 partsParseException = new IllegalStateException(
2804 sm.getString("coyoteRequest.noMultipartConfig"));
2805 return;
2806 } else {
2807 parts = Collections.emptyList();
2808 return;
2809 }
2810 }
2811 }
2812
2813 Parameters parameters = coyoteRequest.getParameters();
2814 parameters.setLimit(getConnector().getMaxParameterCount());
2815
2816 boolean success = false;
2817 try {
2818 File location;
2819 String locationStr = mce.getLocation();
2820 if (locationStr == null || locationStr.length() == 0) {
2821 location = ((File) context.getServletContext().getAttribute(
2822 ServletContext.TEMPDIR));
2823 } else {
2824
2825 location = new File(locationStr);
2826 if (!location.isAbsolute()) {
2827 location = new File(
2828 (File) context.getServletContext().getAttribute(ServletContext.TEMPDIR),
2829 locationStr).getAbsoluteFile();
2830 }
2831 }
2832
2833 if (!location.exists() && context.getCreateUploadTargets()) {
2834 log.warn(sm.getString("coyoteRequest.uploadCreate",
2835 location.getAbsolutePath(), getMappingData().wrapper.getName()));
2836 if (!location.mkdirs()) {
2837 log.warn(sm.getString("coyoteRequest.uploadCreateFail",
2838 location.getAbsolutePath()));
2839 }
2840 }
2841
2842 if (!location.isDirectory()) {
2843 parameters.setParseFailedReason(FailReason.MULTIPART_CONFIG_INVALID);
2844 partsParseException = new IOException(
2845 sm.getString("coyoteRequest.uploadLocationInvalid",
2846 location));
2847 return;
2848 }
2849
2850
2851
2852 DiskFileItemFactory factory = new DiskFileItemFactory();
2853 try {
2854 factory.setRepository(location.getCanonicalFile());
2855 } catch (IOException ioe) {
2856 parameters.setParseFailedReason(FailReason.IO_ERROR);
2857 partsParseException = ioe;
2858 return;
2859 }
2860 factory.setSizeThreshold(mce.getFileSizeThreshold());
2861
2862 ServletFileUpload upload = new ServletFileUpload();
2863 upload.setFileItemFactory(factory);
2864 upload.setFileSizeMax(mce.getMaxFileSize());
2865 upload.setSizeMax(mce.getMaxRequestSize());
2866
2867 parts = new ArrayList<>();
2868 try {
2869 List<FileItem> items =
2870 upload.parseRequest(new ServletRequestContext(this));
2871 int maxPostSize = getConnector().getMaxPostSize();
2872 int postSize = 0;
2873 Charset charset = getCharset();
2874 for (FileItem item : items) {
2875 ApplicationPart part = new ApplicationPart(item, location);
2876 parts.add(part);
2877 if (part.getSubmittedFileName() == null) {
2878 String name = part.getName();
2879 String value = null;
2880 try {
2881 value = part.getString(charset.name());
2882 } catch (UnsupportedEncodingException uee) {
2883
2884 }
2885 if (maxPostSize >= 0) {
2886
2887
2888 postSize += name.getBytes(charset).length;
2889 if (value != null) {
2890
2891 postSize++;
2892
2893 postSize += part.getSize();
2894 }
2895
2896 postSize++;
2897 if (postSize > maxPostSize) {
2898 parameters.setParseFailedReason(FailReason.POST_TOO_LARGE);
2899 throw new IllegalStateException(sm.getString(
2900 "coyoteRequest.maxPostSizeExceeded"));
2901 }
2902 }
2903 parameters.addParameter(name, value);
2904 }
2905 }
2906
2907 success = true;
2908 } catch (InvalidContentTypeException e) {
2909 parameters.setParseFailedReason(FailReason.INVALID_CONTENT_TYPE);
2910 partsParseException = new ServletException(e);
2911 } catch (SizeException e) {
2912 parameters.setParseFailedReason(FailReason.POST_TOO_LARGE);
2913 checkSwallowInput();
2914 partsParseException = new IllegalStateException(e);
2915 } catch (FileUploadException e) {
2916 parameters.setParseFailedReason(FailReason.IO_ERROR);
2917 partsParseException = new IOException(e);
2918 } catch (IllegalStateException e) {
2919
2920 checkSwallowInput();
2921 partsParseException = e;
2922 }
2923 } finally {
2924
2925
2926
2927
2928 if (partsParseException != null || !success) {
2929 parameters.setParseFailedReason(FailReason.UNKNOWN);
2930 }
2931 }
2932 }
2933
2934
2935
2938 @Override
2939 public Part getPart(String name) throws IOException, IllegalStateException,
2940 ServletException {
2941 for (Part part : getParts()) {
2942 if (name.equals(part.getName())) {
2943 return part;
2944 }
2945 }
2946 return null;
2947 }
2948
2949
2950
2951
2952 protected Session doGetSession(boolean create) {
2953
2954
2955 Context context = getContext();
2956 if (context == null) {
2957 return null;
2958 }
2959
2960
2961 if ((session != null) && !session.isValid()) {
2962 session = null;
2963 }
2964 if (session != null) {
2965 return session;
2966 }
2967
2968
2969 Manager manager = context.getManager();
2970 if (manager == null) {
2971 return null;
2972 }
2973 if (requestedSessionId != null) {
2974 try {
2975 session = manager.findSession(requestedSessionId);
2976 } catch (IOException e) {
2977 session = null;
2978 }
2979 if ((session != null) && !session.isValid()) {
2980 session = null;
2981 }
2982 if (session != null) {
2983 session.access();
2984 return session;
2985 }
2986 }
2987
2988
2989 if (!create) {
2990 return null;
2991 }
2992 boolean trackModesIncludesCookie =
2993 context.getServletContext().getEffectiveSessionTrackingModes().contains(SessionTrackingMode.COOKIE);
2994 if (trackModesIncludesCookie && response.getResponse().isCommitted()) {
2995 throw new IllegalStateException(sm.getString("coyoteRequest.sessionCreateCommitted"));
2996 }
2997
2998
2999
3000 String sessionId = getRequestedSessionId();
3001 if (requestedSessionSSL) {
3002
3003
3004 } else if (("/".equals(context.getSessionCookiePath())
3005 && isRequestedSessionIdFromCookie())) {
3006
3016 if (context.getValidateClientProvidedNewSessionId()) {
3017 boolean found = false;
3018 for (Container container : getHost().findChildren()) {
3019 Manager m = ((Context) container).getManager();
3020 if (m != null) {
3021 try {
3022 if (m.findSession(sessionId) != null) {
3023 found = true;
3024 break;
3025 }
3026 } catch (IOException e) {
3027
3028
3029 }
3030 }
3031 }
3032 if (!found) {
3033 sessionId = null;
3034 }
3035 }
3036 } else {
3037 sessionId = null;
3038 }
3039 session = manager.createSession(sessionId);
3040
3041
3042 if (session != null && trackModesIncludesCookie) {
3043 Cookie cookie = ApplicationSessionCookieConfig.createSessionCookie(
3044 context, session.getIdInternal(), isSecure());
3045
3046 response.addSessionCookieInternal(cookie);
3047 }
3048
3049 if (session == null) {
3050 return null;
3051 }
3052
3053 session.access();
3054 return session;
3055 }
3056
3057 protected String unescape(String s) {
3058 if (s==null) {
3059 return null;
3060 }
3061 if (s.indexOf('\\') == -1) {
3062 return s;
3063 }
3064 StringBuilder buf = new StringBuilder();
3065 for (int i=0; i<s.length(); i++) {
3066 char c = s.charAt(i);
3067 if (c!='\\') {
3068 buf.append(c);
3069 } else {
3070 if (++i >= s.length()) {
3071 throw new IllegalArgumentException();
3072 }
3073 c = s.charAt(i);
3074 buf.append(c);
3075 }
3076 }
3077 return buf.toString();
3078 }
3079
3080
3084 protected void parseCookies() {
3085 if (cookiesParsed) {
3086 return;
3087 }
3088
3089 cookiesParsed = true;
3090
3091 ServerCookies serverCookies = coyoteRequest.getCookies();
3092 serverCookies.setLimit(connector.getMaxCookieCount());
3093 CookieProcessor cookieProcessor = getContext().getCookieProcessor();
3094 cookieProcessor.parseCookieHeader(coyoteRequest.getMimeHeaders(), serverCookies);
3095 }
3096
3097
3101 protected void convertCookies() {
3102 if (cookiesConverted) {
3103 return;
3104 }
3105
3106 cookiesConverted = true;
3107
3108 if (getContext() == null) {
3109 return;
3110 }
3111
3112 parseCookies();
3113
3114 ServerCookies serverCookies = coyoteRequest.getCookies();
3115 CookieProcessor cookieProcessor = getContext().getCookieProcessor();
3116
3117 int count = serverCookies.getCookieCount();
3118 if (count <= 0) {
3119 return;
3120 }
3121
3122 cookies = new Cookie[count];
3123
3124 int idx=0;
3125 for (int i = 0; i < count; i++) {
3126 ServerCookie scookie = serverCookies.getCookie(i);
3127 try {
3128
3129 Cookie cookie = new Cookie(scookie.getName().toString(),null);
3130 int version = scookie.getVersion();
3131 cookie.setVersion(version);
3132 scookie.getValue().getByteChunk().setCharset(cookieProcessor.getCharset());
3133 cookie.setValue(unescape(scookie.getValue().toString()));
3134 cookie.setPath(unescape(scookie.getPath().toString()));
3135 String domain = scookie.getDomain().toString();
3136 if (domain!=null) {
3137 cookie.setDomain(unescape(domain));
3138 }
3139 String comment = scookie.getComment().toString();
3140 cookie.setComment(version==1?unescape(comment):null);
3141 cookies[idx++] = cookie;
3142 } catch(IllegalArgumentException e) {
3143
3144 }
3145 }
3146 if( idx < count ) {
3147 Cookie [] ncookies = new Cookie[idx];
3148 System.arraycopy(cookies, 0, ncookies, 0, idx);
3149 cookies = ncookies;
3150 }
3151 }
3152
3153
3154
3157 protected void parseParameters() {
3158
3159 parametersParsed = true;
3160
3161 Parameters parameters = coyoteRequest.getParameters();
3162 boolean success = false;
3163 try {
3164
3165 parameters.setLimit(getConnector().getMaxParameterCount());
3166
3167
3168
3169 Charset charset = getCharset();
3170
3171 boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI();
3172 parameters.setCharset(charset);
3173 if (useBodyEncodingForURI) {
3174 parameters.setQueryStringCharset(charset);
3175 }
3176
3177
3178
3179 parameters.handleQueryParameters();
3180
3181 if (usingInputStream || usingReader) {
3182 success = true;
3183 return;
3184 }
3185
3186 String contentType = getContentType();
3187 if (contentType == null) {
3188 contentType = "";
3189 }
3190 int semicolon = contentType.indexOf(';');
3191 if (semicolon >= 0) {
3192 contentType = contentType.substring(0, semicolon).trim();
3193 } else {
3194 contentType = contentType.trim();
3195 }
3196
3197 if ("multipart/form-data".equals(contentType)) {
3198 parseParts(false);
3199 success = true;
3200 return;
3201 }
3202
3203 if( !getConnector().isParseBodyMethod(getMethod()) ) {
3204 success = true;
3205 return;
3206 }
3207
3208 if (!("application/x-www-form-urlencoded".equals(contentType))) {
3209 success = true;
3210 return;
3211 }
3212
3213 int len = getContentLength();
3214
3215 if (len > 0) {
3216 int maxPostSize = connector.getMaxPostSize();
3217 if ((maxPostSize >= 0) && (len > maxPostSize)) {
3218 Context context = getContext();
3219 if (context != null && context.getLogger().isDebugEnabled()) {
3220 context.getLogger().debug(
3221 sm.getString("coyoteRequest.postTooLarge"));
3222 }
3223 checkSwallowInput();
3224 parameters.setParseFailedReason(FailReason.POST_TOO_LARGE);
3225 return;
3226 }
3227 byte[] formData = null;
3228 if (len < CACHED_POST_LEN) {
3229 if (postData == null) {
3230 postData = new byte[CACHED_POST_LEN];
3231 }
3232 formData = postData;
3233 } else {
3234 formData = new byte[len];
3235 }
3236 try {
3237 if (readPostBody(formData, len) != len) {
3238 parameters.setParseFailedReason(FailReason.REQUEST_BODY_INCOMPLETE);
3239 return;
3240 }
3241 } catch (IOException e) {
3242
3243 Context context = getContext();
3244 if (context != null && context.getLogger().isDebugEnabled()) {
3245 context.getLogger().debug(
3246 sm.getString("coyoteRequest.parseParameters"), e);
3247 }
3248 parameters.setParseFailedReason(FailReason.CLIENT_DISCONNECT);
3249 return;
3250 }
3251 parameters.processParameters(formData, 0, len);
3252 } else if ("chunked".equalsIgnoreCase(
3253 coyoteRequest.getHeader("transfer-encoding"))) {
3254 byte[] formData = null;
3255 try {
3256 formData = readChunkedPostBody();
3257 } catch (IllegalStateException ise) {
3258
3259 parameters.setParseFailedReason(FailReason.POST_TOO_LARGE);
3260 Context context = getContext();
3261 if (context != null && context.getLogger().isDebugEnabled()) {
3262 context.getLogger().debug(
3263 sm.getString("coyoteRequest.parseParameters"),
3264 ise);
3265 }
3266 return;
3267 } catch (IOException e) {
3268
3269 parameters.setParseFailedReason(FailReason.CLIENT_DISCONNECT);
3270 Context context = getContext();
3271 if (context != null && context.getLogger().isDebugEnabled()) {
3272 context.getLogger().debug(
3273 sm.getString("coyoteRequest.parseParameters"), e);
3274 }
3275 return;
3276 }
3277 if (formData != null) {
3278 parameters.processParameters(formData, 0, formData.length);
3279 }
3280 }
3281 success = true;
3282 } finally {
3283 if (!success) {
3284 parameters.setParseFailedReason(FailReason.UNKNOWN);
3285 }
3286 }
3287
3288 }
3289
3290
3291
3299 protected int readPostBody(byte[] body, int len)
3300 throws IOException {
3301
3302 int offset = 0;
3303 do {
3304 int inputLen = getStream().read(body, offset, len - offset);
3305 if (inputLen <= 0) {
3306 return offset;
3307 }
3308 offset += inputLen;
3309 } while ((len - offset) > 0);
3310 return len;
3311
3312 }
3313
3314
3315
3321 protected byte[] readChunkedPostBody() throws IOException {
3322 ByteChunk body = new ByteChunk();
3323
3324 byte[] buffer = new byte[CACHED_POST_LEN];
3325
3326 int len = 0;
3327 while (len > -1) {
3328 len = getStream().read(buffer, 0, CACHED_POST_LEN);
3329 if (connector.getMaxPostSize() >= 0 &&
3330 (body.getLength() + len) > connector.getMaxPostSize()) {
3331
3332 checkSwallowInput();
3333 throw new IllegalStateException(
3334 sm.getString("coyoteRequest.chunkedPostTooLarge"));
3335 }
3336 if (len > 0) {
3337 body.append(buffer, 0, len);
3338 }
3339 }
3340 if (body.getLength() == 0) {
3341 return null;
3342 }
3343 if (body.getLength() < body.getBuffer().length) {
3344 int length = body.getLength();
3345 byte[] result = new byte[length];
3346 System.arraycopy(body.getBuffer(), 0, result, 0, length);
3347 return result;
3348 }
3349
3350 return body.getBuffer();
3351 }
3352
3353
3354
3357 protected void parseLocales() {
3358
3359 localesParsed = true;
3360
3361
3362
3363
3364
3365 TreeMap<Double, ArrayList<Locale>> locales = new TreeMap<>();
3366
3367 Enumeration<String> values = getHeaders("accept-language");
3368
3369 while (values.hasMoreElements()) {
3370 String value = values.nextElement();
3371 parseLocalesHeader(value, locales);
3372 }
3373
3374
3375
3376 for (ArrayList<Locale> list : locales.values()) {
3377 for (Locale locale : list) {
3378 addLocale(locale);
3379 }
3380 }
3381 }
3382
3383
3384
3390 protected void parseLocalesHeader(String value, TreeMap<Double, ArrayList<Locale>> locales) {
3391
3392 List<AcceptLanguage> acceptLanguages;
3393 try {
3394 acceptLanguages = AcceptLanguage.parse(new StringReader(value));
3395 } catch (IOException e) {
3396
3397
3398 return;
3399 }
3400
3401 for (AcceptLanguage acceptLanguage : acceptLanguages) {
3402
3403 Double key = Double.valueOf(-acceptLanguage.getQuality());
3404 ArrayList<Locale> values = locales.get(key);
3405 if (values == null) {
3406 values = new ArrayList<>();
3407 locales.put(key, values);
3408 }
3409 values.add(acceptLanguage.getLocale());
3410 }
3411 }
3412
3413
3414
3415
3416 private static interface SpecialAttributeAdapter {
3417 Object get(Request request, String name);
3418
3419 void set(Request request, String name, Object value);
3420
3421
3422
3423 }
3424
3425 private static final Map<String, SpecialAttributeAdapter> specialAttributes = new HashMap<>();
3426
3427 static {
3428 specialAttributes.put(Globals.DISPATCHER_TYPE_ATTR,
3429 new SpecialAttributeAdapter() {
3430 @Override
3431 public Object get(Request request, String name) {
3432 return (request.internalDispatcherType == null) ? DispatcherType.REQUEST
3433 : request.internalDispatcherType;
3434 }
3435
3436 @Override
3437 public void set(Request request, String name, Object value) {
3438 request.internalDispatcherType = (DispatcherType) value;
3439 }
3440 });
3441 specialAttributes.put(Globals.DISPATCHER_REQUEST_PATH_ATTR,
3442 new SpecialAttributeAdapter() {
3443 @Override
3444 public Object get(Request request, String name) {
3445 return (request.requestDispatcherPath == null) ? request
3446 .getRequestPathMB().toString()
3447 : request.requestDispatcherPath.toString();
3448 }
3449
3450 @Override
3451 public void set(Request request, String name, Object value) {
3452 request.requestDispatcherPath = value;
3453 }
3454 });
3455 specialAttributes.put(Globals.ASYNC_SUPPORTED_ATTR,
3456 new SpecialAttributeAdapter() {
3457 @Override
3458 public Object get(Request request, String name) {
3459 return request.asyncSupported;
3460 }
3461
3462 @Override
3463 public void set(Request request, String name, Object value) {
3464 Boolean oldValue = request.asyncSupported;
3465 request.asyncSupported = (Boolean)value;
3466 request.notifyAttributeAssigned(name, value, oldValue);
3467 }
3468 });
3469 specialAttributes.put(Globals.GSS_CREDENTIAL_ATTR,
3470 new SpecialAttributeAdapter() {
3471 @Override
3472 public Object get(Request request, String name) {
3473 if (request.userPrincipal instanceof TomcatPrincipal) {
3474 return ((TomcatPrincipal) request.userPrincipal)
3475 .getGssCredential();
3476 }
3477 return null;
3478 }
3479
3480 @Override
3481 public void set(Request request, String name, Object value) {
3482
3483 }
3484 });
3485 specialAttributes.put(Globals.PARAMETER_PARSE_FAILED_ATTR,
3486 new SpecialAttributeAdapter() {
3487 @Override
3488 public Object get(Request request, String name) {
3489 if (request.getCoyoteRequest().getParameters()
3490 .isParseFailed()) {
3491 return Boolean.TRUE;
3492 }
3493 return null;
3494 }
3495
3496 @Override
3497 public void set(Request request, String name, Object value) {
3498
3499 }
3500 });
3501 specialAttributes.put(Globals.PARAMETER_PARSE_FAILED_REASON_ATTR,
3502 new SpecialAttributeAdapter() {
3503 @Override
3504 public Object get(Request request, String name) {
3505 return request.getCoyoteRequest().getParameters().getParseFailedReason();
3506 }
3507
3508 @Override
3509 public void set(Request request, String name, Object value) {
3510
3511 }
3512 });
3513 specialAttributes.put(Globals.SENDFILE_SUPPORTED_ATTR,
3514 new SpecialAttributeAdapter() {
3515 @Override
3516 public Object get(Request request, String name) {
3517 return Boolean.valueOf(
3518 request.getConnector().getProtocolHandler(
3519 ).isSendfileSupported() && request.getCoyoteRequest().getSendfile());
3520 }
3521 @Override
3522 public void set(Request request, String name, Object value) {
3523
3524 }
3525 });
3526
3527 for (SimpleDateFormat sdf : formatsTemplate) {
3528 sdf.setTimeZone(GMT_ZONE);
3529 }
3530 }
3531 }
3532