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