1
2
3
4
5
6
7
8
9
10
11
12 package ch.qos.logback.access.common.spi;
13
14 import ch.qos.logback.access.common.AccessConstants;
15 import ch.qos.logback.access.common.pattern.AccessConverter;
16 import ch.qos.logback.access.common.servlet.Util;
17 import ch.qos.logback.core.Context;
18 import ch.qos.logback.core.spi.SequenceNumberGenerator;
19
20 import jakarta.servlet.http.Cookie;
21 import jakarta.servlet.http.HttpServletRequest;
22 import jakarta.servlet.http.HttpServletResponse;
23 import jakarta.servlet.http.HttpSession;
24
25 import java.io.Serializable;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Enumeration;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.TreeMap;
33 import java.util.Vector;
34
35
36
37
38
39
40
41
42
43
44
45 public class AccessEvent implements Serializable, IAccessEvent {
46
47 private static final String[] NA_STRING_ARRAY = new String[] { NA };
48
49 private static final long serialVersionUID = 866718993618836343L;
50
51 private static final String EMPTY = "";
52
53 private transient final HttpServletRequest httpRequest;
54 private transient final HttpServletResponse httpResponse;
55
56 String queryString;
57 String requestURI;
58 String requestURL;
59 String remoteHost;
60 String remoteUser;
61 String remoteAddr;
62 String threadName;
63 String protocol;
64 String method;
65 String serverName;
66 String requestContent;
67 String responseContent;
68 String sessionID;
69 long elapsedTime;
70
71 Map<String, String> requestHeaderMap;
72 Map<String, String[]> requestParameterMap;
73 Map<String, String> responseHeaderMap;
74 Map<String, Object> attributeMap;
75
76 List<Cookie> cookieList;
77
78 long contentLength = SENTINEL;
79 int statusCode = SENTINEL;
80 int localPort = SENTINEL;
81
82 transient ServerAdapter serverAdapter;
83
84
85
86
87 private long timeStamp = 0;
88
89 private long sequenceNumber = 0;
90
91 public AccessEvent(Context context, HttpServletRequest httpRequest, HttpServletResponse httpResponse,
92 ServerAdapter adapter) {
93 this.httpRequest = httpRequest;
94 this.httpResponse = httpResponse;
95 this.timeStamp = System.currentTimeMillis();
96
97 SequenceNumberGenerator sng = context.getSequenceNumberGenerator();
98 if (sng != null) {
99 this.sequenceNumber = sng.nextSequenceNumber();
100 }
101 this.serverAdapter = adapter;
102 this.elapsedTime = calculateElapsedTime();
103 }
104
105
106
107
108
109
110 @Override
111 public HttpServletRequest getRequest() {
112 return httpRequest;
113 }
114
115
116
117
118
119
120 @Override
121 public HttpServletResponse getResponse() {
122 return httpResponse;
123 }
124
125 @Override
126 public long getTimeStamp() {
127 return timeStamp;
128 }
129
130 public void setTimeStamp(long timeStamp) {
131 this.timeStamp = timeStamp;
132 }
133
134 public long getSequenceNumber() {
135 return sequenceNumber;
136 }
137
138 public void setSequenceNumber(long sequenceNumber) {
139 this.sequenceNumber = sequenceNumber;
140 }
141
142
143
144
145 public void setThreadName(String threadName) {
146 this.threadName = threadName;
147 }
148
149 @Override
150 public String getThreadName() {
151 return threadName == null ? NA : threadName;
152 }
153
154 @Override
155 public String getRequestURI() {
156 if (requestURI == null) {
157 if (httpRequest != null) {
158 requestURI = httpRequest.getRequestURI();
159 } else {
160 requestURI = NA;
161 }
162 }
163 return requestURI;
164 }
165
166 @Override
167 public String getQueryString() {
168 if (queryString == null) {
169 if (httpRequest != null) {
170 StringBuilder buf = new StringBuilder();
171 final String qStr = httpRequest.getQueryString();
172 if (qStr != null) {
173 buf.append(AccessConverter.QUESTION_CHAR);
174 buf.append(qStr);
175 }
176 queryString = buf.toString();
177 } else {
178 queryString = NA;
179 }
180 }
181 return queryString;
182 }
183
184
185
186
187 @Override
188 public String getRequestURL() {
189 if(requestURL != null)
190 return requestURL;
191
192 if (httpRequest != null) {
193 StringBuilder buf = new StringBuilder();
194 buf.append(getMethod());
195 buf.append(AccessConverter.SPACE_CHAR);
196 buf.append(getRequestURI());
197 buf.append(getQueryString());
198 buf.append(AccessConverter.SPACE_CHAR);
199 buf.append(getProtocol());
200 requestURL = buf.toString();
201 } else {
202 requestURL = NA;
203 }
204 return requestURL;
205 }
206
207 @Override
208 public String getRemoteHost() {
209 if (remoteHost == null) {
210 if (httpRequest != null) {
211
212
213 remoteHost = httpRequest.getRemoteHost();
214 } else {
215 remoteHost = NA;
216 }
217 }
218 return remoteHost;
219 }
220
221 @Override
222 public String getRemoteUser() {
223 if (remoteUser == null) {
224 if (httpRequest != null) {
225 remoteUser = httpRequest.getRemoteUser();
226 } else {
227 remoteUser = NA;
228 }
229 }
230 return remoteUser;
231 }
232
233 @Override
234 public String getProtocol() {
235 if (protocol == null) {
236 if (httpRequest != null) {
237 protocol = httpRequest.getProtocol();
238 } else {
239 protocol = NA;
240 }
241 }
242 return protocol;
243 }
244
245 @Override
246 public String getMethod() {
247 if (method == null) {
248 if (httpRequest != null) {
249 method = httpRequest.getMethod();
250 } else {
251 method = NA;
252 }
253 }
254 return method;
255 }
256
257 @Override
258 public String getSessionID() {
259 if (sessionID == null) {
260 if (httpRequest != null) {
261 if (httpRequest instanceof WrappedHttpRequest) {
262 WrappedHttpRequest wrappedHttpRequest = (WrappedHttpRequest) httpRequest;
263 sessionID = wrappedHttpRequest.getSessionID();
264 } else {
265 final HttpSession session = httpRequest.getSession(false);
266 if (session != null) {
267 sessionID = session.getId();
268 }
269 }
270 } else {
271 sessionID = NA;
272 }
273 }
274 return sessionID;
275 }
276
277 @Override
278 public String getServerName() {
279 if (serverName == null) {
280 if (httpRequest != null) {
281 serverName = httpRequest.getServerName();
282 } else {
283 serverName = NA;
284 }
285 }
286 return serverName;
287 }
288
289 @Override
290 public String getRemoteAddr() {
291 if (remoteAddr == null) {
292 if (httpRequest != null) {
293 remoteAddr = httpRequest.getRemoteAddr();
294 } else {
295 remoteAddr = NA;
296 }
297 }
298 return remoteAddr;
299 }
300
301 @Override
302 public String getRequestHeader(String key) {
303 String result = null;
304 key = key.toLowerCase();
305 if (requestHeaderMap == null) {
306 if (httpRequest != null) {
307 buildRequestHeaderMap();
308 result = requestHeaderMap.get(key);
309 }
310 } else {
311 result = requestHeaderMap.get(key);
312 }
313
314 if (result != null) {
315 return result;
316 } else {
317 return NA;
318 }
319 }
320
321 @Override
322 public Enumeration<String> getRequestHeaderNames() {
323
324 if (httpRequest == null) {
325 Vector<String> list = new Vector<String>(getRequestHeaderMap().keySet());
326 return list.elements();
327 }
328 return httpRequest.getHeaderNames();
329 }
330
331 @Override
332 public Map<String, String> getRequestHeaderMap() {
333 if (requestHeaderMap == null) {
334 buildRequestHeaderMap();
335 }
336 return requestHeaderMap;
337 }
338
339 public void buildRequestHeaderMap() {
340 if (httpRequest instanceof WrappedHttpRequest) {
341 WrappedHttpRequest whr = (WrappedHttpRequest) httpRequest;
342 requestHeaderMap = whr.buildRequestHeaderMap();
343 } else {
344
345
346
347 requestHeaderMap = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
348 Enumeration<String> e = httpRequest.getHeaderNames();
349 if (e == null) {
350 return;
351 }
352 while (e.hasMoreElements()) {
353 String key = e.nextElement();
354 requestHeaderMap.put(key, httpRequest.getHeader(key));
355 }
356 }
357 }
358
359 public void buildRequestParameterMap() {
360 if (httpRequest instanceof WrappedHttpRequest) {
361 WrappedHttpRequest whr = (WrappedHttpRequest) httpRequest;
362 requestParameterMap = whr.buildRequestParameterMap();
363 } else {
364
365 requestParameterMap = new HashMap<String, String[]>();
366 try {
367 Enumeration<String> e = httpRequest.getParameterNames();
368 if (e == null) {
369 return;
370 }
371 while (e.hasMoreElements()) {
372 String key = e.nextElement();
373 requestParameterMap.put(key, httpRequest.getParameterValues(key));
374 }
375 } catch (Throwable t) {
376
377
378
379
380
381 t.printStackTrace();
382 }
383 }
384 }
385
386 @Override
387 public Map<String, String[]> getRequestParameterMap() {
388 if (requestParameterMap == null) {
389 buildRequestParameterMap();
390 }
391 return requestParameterMap;
392 }
393
394 @Override
395 public String getAttribute(String key) {
396 Object value = null;
397 if (attributeMap != null) {
398
399
400 value = attributeMap.get(key);
401 } else if (httpRequest != null) {
402
403 value = httpRequest.getAttribute(key);
404 }
405
406 return value != null ? value.toString() : NA;
407 }
408
409 private void copyAttributeMap() {
410
411 if (httpRequest == null) {
412 return;
413 }
414
415
416 if (attributeMap != null) {
417 return;
418 }
419
420 attributeMap = new HashMap<String, Object>();
421
422 Enumeration<String> names = httpRequest.getAttributeNames();
423 while (names.hasMoreElements()) {
424 String name = names.nextElement();
425
426 Object value = httpRequest.getAttribute(name);
427 if (shouldCopyAttribute(name, value)) {
428 attributeMap.put(name, value);
429 }
430 }
431 }
432
433 private boolean shouldCopyAttribute(String name, Object value) {
434 if (AccessConstants.LB_INPUT_BUFFER.equals(name) || AccessConstants.LB_OUTPUT_BUFFER.equals(name)) {
435
436
437 return false;
438 } else if (value == null) {
439
440
441
442 return false;
443 } else {
444
445 return value instanceof Serializable;
446 }
447 }
448
449 @Override
450 public String[] getRequestParameter(String key) {
451 String[] value = null;
452
453 if (requestParameterMap != null) {
454 value = requestParameterMap.get(key);
455 } else if (httpRequest != null) {
456 value = httpRequest.getParameterValues(key);
457 }
458
459 return (value != null) ? value : NA_STRING_ARRAY;
460 }
461
462
463
464
465
466
467
468 public List<Cookie> getCookies() {
469
470 if (cookieList != null)
471 return cookieList;
472
473 if (httpRequest == null) {
474 cookieList = List.of();
475 return cookieList;
476 }
477
478 Cookie[] cookieArray = httpRequest.getCookies();
479 this.cookieList = (cookieArray != null ? List.of(cookieArray) : List.of());
480 return this.cookieList;
481 }
482
483 @Override
484 public String getCookie(String key) {
485 List<Cookie> cookies = getCookies();
486 Cookie matchingCookie = cookies.stream().filter(c -> c.getName().equals(key)).findFirst().orElse(null);
487 return matchingCookie != null ? matchingCookie.getValue() : NA;
488 }
489
490 @Override
491 public long getContentLength() {
492 if (contentLength == SENTINEL) {
493 if (httpResponse != null) {
494 contentLength = serverAdapter.getContentLength();
495 return contentLength;
496 }
497 }
498 return contentLength;
499 }
500
501 public int getStatusCode() {
502 if (statusCode == SENTINEL) {
503 if (httpResponse != null) {
504 statusCode = serverAdapter.getStatusCode();
505 }
506 }
507 return statusCode;
508 }
509
510 public long getElapsedSeconds() {
511 return elapsedTime < 0 ? elapsedTime : elapsedTime / 1000;
512 }
513
514 public long getElapsedTime() {
515 return elapsedTime;
516 }
517
518 private long calculateElapsedTime() {
519 if (serverAdapter.getRequestTimestamp() < 0) {
520 return -1;
521 }
522 return getTimeStamp() - serverAdapter.getRequestTimestamp();
523 }
524
525 public String getRequestContent() {
526 if (requestContent != null) {
527 return requestContent;
528 }
529
530 if (Util.isFormUrlEncoded(httpRequest)) {
531 StringBuilder buf = new StringBuilder();
532
533 try {
534 Enumeration<String> pramEnumeration = httpRequest.getParameterNames();
535
536
537
538 int count = 0;
539 while (pramEnumeration.hasMoreElements()) {
540
541 String key = pramEnumeration.nextElement();
542 if (count++ != 0) {
543 buf.append("&");
544 }
545 buf.append(key);
546 buf.append("=");
547 String val = httpRequest.getParameter(key);
548 if (val != null) {
549 buf.append(val);
550 } else {
551 buf.append("");
552 }
553 }
554 } catch (Throwable t) {
555
556
557
558
559
560
561 t.printStackTrace();
562 }
563 requestContent = buf.toString();
564 } else {
565
566 byte[] inputBuffer = (byte[]) httpRequest.getAttribute(AccessConstants.LB_INPUT_BUFFER);
567
568 if (inputBuffer != null) {
569 requestContent = new String(inputBuffer);
570 }
571
572 if (requestContent == null || requestContent.length() == 0) {
573 requestContent = EMPTY;
574 }
575 }
576
577 return requestContent;
578 }
579
580 public String getResponseContent() {
581 if (responseContent != null) {
582 return responseContent;
583 }
584
585 if (Util.isImageResponse(httpResponse)) {
586 responseContent = "[IMAGE CONTENTS SUPPRESSED]";
587 } else {
588
589
590 byte[] outputBuffer = (byte[]) httpRequest.getAttribute(AccessConstants.LB_OUTPUT_BUFFER);
591
592 if (outputBuffer != null) {
593 responseContent = new String(outputBuffer);
594 }
595 if (responseContent == null || responseContent.length() == 0) {
596 responseContent = EMPTY;
597 }
598 }
599
600 return responseContent;
601 }
602
603 public int getLocalPort() {
604 if (localPort == SENTINEL) {
605 if (httpRequest != null) {
606 localPort = httpRequest.getLocalPort();
607 }
608
609 }
610 return localPort;
611 }
612
613 public ServerAdapter getServerAdapter() {
614 return serverAdapter;
615 }
616
617 public String getResponseHeader(String key) {
618 buildResponseHeaderMap();
619 return responseHeaderMap.get(key);
620 }
621
622 void buildResponseHeaderMap() {
623 if (responseHeaderMap == null) {
624 responseHeaderMap = serverAdapter.buildResponseHeaderMap();
625 }
626 }
627
628 public Map<String, String> getResponseHeaderMap() {
629 buildResponseHeaderMap();
630 return responseHeaderMap;
631 }
632
633 public List<String> getResponseHeaderNameList() {
634 buildResponseHeaderMap();
635 return new ArrayList<String>(responseHeaderMap.keySet());
636 }
637
638 public void prepareForDeferredProcessing() {
639 getRequestHeaderMap();
640 getRequestParameterMap();
641 getResponseHeaderMap();
642 getLocalPort();
643 getMethod();
644 getProtocol();
645 getRemoteAddr();
646 getRemoteHost();
647 getRemoteUser();
648 getRequestURI();
649 getRequestURL();
650 getServerName();
651 getTimeStamp();
652 getElapsedTime();
653
654 getCookies();
655
656 getStatusCode();
657 getContentLength();
658 getRequestContent();
659 getResponseContent();
660
661 copyAttributeMap();
662 }
663 }