View Javadoc

1   package ch.qos.logback.access.spi;
2   
3   import java.io.Serializable;
4   import java.util.ArrayList;
5   import java.util.Enumeration;
6   import java.util.HashMap;
7   import java.util.List;
8   import java.util.Map;
9   import java.util.Vector;
10  
11  import javax.servlet.http.Cookie;
12  import javax.servlet.http.HttpServletRequest;
13  import javax.servlet.http.HttpServletResponse;
14  
15  import ch.qos.logback.access.AccessConstants;
16  import ch.qos.logback.access.pattern.AccessConverter;
17  import ch.qos.logback.access.servlet.Util;
18  
19  // Contributors:  Joern Huxhorn (see also bug #110)
20  
21  /**
22   * The Access module's internal representation of logging events. When the
23   * logging component instance is called in the container to log then a
24   * <code>AccessEvent</code> instance is created. This instance is passed
25   * around to the different logback components.
26   * 
27   * @author Ceki G&uuml;lc&uuml;
28   * @author S&eacute;bastien Pennec
29   */
30  public class AccessEvent implements Serializable {
31  
32    
33    private static final long serialVersionUID = 866718993618836343L;
34    
35    public final static String NA = "-";
36    public final static String[] NA_STRING_ARRAY = new String[] { AccessEvent.NA };
37  
38    public final static String EMPTY = "";
39    public static final int SENTINEL = -1;
40  
41    private transient final HttpServletRequest httpRequest;
42    private transient final HttpServletResponse httpResponse;
43  
44    String requestURI;
45    String requestURL;
46    String remoteHost;
47    String remoteUser;
48    String remoteAddr;
49    String protocol;
50    String method;
51    String serverName;
52    String requestContent;
53    String responseContent;
54  
55    Map<String, String> requestHeaderMap;
56    Map<String, String[]> requestParameterMap;
57    Map<String, String> responseHeaderMap;
58  
59    long contentLength = SENTINEL;
60    int statusCode = SENTINEL;
61    int localPort = SENTINEL;
62  
63    transient ServerAdapter serverAdapter;
64  
65    /**
66     * The number of milliseconds elapsed from 1/1/1970 until logging event was
67     * created.
68     */
69    private long timeStamp = 0;
70  
71    public AccessEvent(HttpServletRequest httpRequest,
72        HttpServletResponse httpResponse, ServerAdapter adapter) {
73      this.httpRequest = httpRequest;
74      this.httpResponse = httpResponse;
75      this.timeStamp = System.currentTimeMillis();
76      this.serverAdapter = adapter;
77    }
78  
79    /**
80     * Returns the underlying HttpServletRequest. After serialization the returned 
81     * value will be null. 
82     * 
83     * @return
84     */
85    public HttpServletRequest getRequest() {
86      return httpRequest;
87    }
88  
89    /**
90     * Returns the underlying HttpServletResponse. After serialization the returned 
91     * value will be null. 
92     * 
93     * @return
94     */
95    public HttpServletResponse getResponse() {
96      return httpResponse;
97    }
98  
99    public long getTimeStamp() {
100     return timeStamp;
101   }
102 
103   public void setTimeStamp(long timeStamp) {
104     if (this.timeStamp != 0) {
105       throw new IllegalStateException(
106           "timeStamp has been already set for this event.");
107     } else {
108       this.timeStamp = timeStamp;
109     }
110   }
111 
112   public String getRequestURI() {
113     if (requestURI == null) {
114       if (httpRequest != null) {
115         requestURI = httpRequest.getRequestURI();
116       } else {
117         requestURI = AccessEvent.NA;
118       }
119     }
120     return requestURI;
121   }
122 
123   /**
124    * The first line of the request.
125    */
126   public String getRequestURL() {
127     if (requestURL == null) {
128       if (httpRequest != null) {
129         StringBuffer buf = new StringBuffer();
130         buf.append(httpRequest.getMethod());
131         buf.append(AccessConverter.SPACE_CHAR);
132         buf.append(httpRequest.getRequestURI());
133         final String qStr = httpRequest.getQueryString();
134         if (qStr != null) {
135           buf.append(AccessConverter.QUESTION_CHAR);
136           buf.append(qStr);
137         }
138         buf.append(AccessConverter.SPACE_CHAR);
139         buf.append(httpRequest.getProtocol());
140         requestURL = buf.toString();
141       } else {
142         requestURL = AccessEvent.NA;
143       }
144     }
145     return requestURL;
146   }
147 
148   public String getRemoteHost() {
149     if (remoteHost == null) {
150       if (httpRequest != null) {
151         // the underlying implementation of HttpServletRequest will
152         // determine if remote lookup will be performed
153         remoteHost = httpRequest.getRemoteHost();
154       } else {
155         remoteHost = AccessEvent.NA;
156       }
157     }
158     return remoteHost;
159   }
160 
161   public String getRemoteUser() {
162     if (remoteUser == null) {
163       if (httpRequest != null) {
164         remoteUser = httpRequest.getRemoteUser();
165       } else {
166         remoteUser = AccessEvent.NA;
167       }
168     }
169     return remoteUser;
170   }
171 
172   public String getProtocol() {
173     if (protocol == null) {
174       if (httpRequest != null) {
175         protocol = httpRequest.getProtocol();
176       } else {
177         protocol = AccessEvent.NA;
178       }
179     }
180     return protocol;
181   }
182 
183   public String getMethod() {
184     if (method == null) {
185       if (httpRequest != null) {
186         method = httpRequest.getMethod();
187       } else {
188         method = AccessEvent.NA;
189       }
190     }
191     return method;
192   }
193 
194   public String getServerName() {
195     if (serverName == null) {
196       if (httpRequest != null) {
197         serverName = httpRequest.getServerName();
198       } else {
199         serverName = AccessEvent.NA;
200       }
201     }
202     return serverName;
203   }
204 
205   public String getRemoteAddr() {
206     if (remoteAddr == null) {
207       if (httpRequest != null) {
208         remoteAddr = httpRequest.getRemoteAddr();
209       } else {
210         remoteAddr = AccessEvent.NA;
211       }
212     }
213     return remoteAddr;
214   }
215 
216   public String getRequestHeader(String key) {
217     String result = null;
218     if (requestHeaderMap == null) {
219       if (httpRequest != null) {
220         buildRequestHeaderMap();
221         result = requestHeaderMap.get(key);
222       }
223     } else {
224       result = requestHeaderMap.get(key);
225     }
226 
227     if (result != null) {
228       return result;
229     } else {
230       return AccessEvent.NA;
231     }
232   }
233 
234   public Enumeration getRequestHeaderNames() {
235     // post-serialization
236     if (httpRequest == null) {
237       Vector<String> list = new Vector<String>(getRequestHeaderMap().keySet());
238       return list.elements();
239     }
240     return httpRequest.getHeaderNames();
241 
242   }
243 
244   public Map<String, String> getRequestHeaderMap() {
245     if (requestHeaderMap == null) {
246       buildRequestHeaderMap();
247     }
248     return requestHeaderMap;
249   }
250 
251   public void buildRequestHeaderMap() {
252     requestHeaderMap = new HashMap<String, String>();
253     Enumeration e = httpRequest.getHeaderNames();
254     if (e == null) {
255       return;
256     }
257     while (e.hasMoreElements()) {
258       String key = (String) e.nextElement();
259       requestHeaderMap.put(key, httpRequest.getHeader(key));
260     }
261   }
262 
263   public void buildRequestParameterMap() {
264     requestParameterMap = new HashMap<String, String[]>();
265     Enumeration e = httpRequest.getParameterNames();
266     if (e == null) {
267       return;
268     }
269     while (e.hasMoreElements()) {
270       String key = (String) e.nextElement();
271       requestParameterMap.put(key, httpRequest.getParameterValues(key));
272     }
273   }
274 
275   public Map<String, String[]> getRequestParameterMap() {
276     if (requestParameterMap == null) {
277       buildRequestParameterMap();
278     }
279     return requestParameterMap;
280   }
281 
282   /**
283    * Attributes are not serialized
284    * 
285    * @param key
286    */
287   public String getAttribute(String key) {
288     if (httpRequest != null) {
289       Object value = httpRequest.getAttribute(key);
290       if (value == null) {
291         return AccessEvent.NA;
292       } else {
293         return value.toString();
294       }
295     } else {
296       return AccessEvent.NA;
297     }
298   }
299 
300   public String[] getRequestParameter(String key) {
301     if (httpRequest != null) {
302       String[] value = httpRequest.getParameterValues(key);
303       if (value == null) {
304         return NA_STRING_ARRAY;
305       } else {
306         return value;
307       }
308     } else {
309       return NA_STRING_ARRAY;
310     }
311   }
312 
313   public String getCookie(String key) {
314 
315     if (httpRequest != null) {
316       Cookie[] cookieArray = httpRequest.getCookies();
317       if (cookieArray == null) {
318         return AccessEvent.NA;
319       }
320 
321       for (Cookie cookie : cookieArray) {
322         if (key.equals(cookie.getName())) {
323           return cookie.getValue();
324         }
325       }
326     }
327     return AccessEvent.NA;
328   }
329 
330   public long getContentLength() {
331     if (contentLength == SENTINEL) {
332       if (httpResponse != null) {
333         contentLength = serverAdapter.getContentLength();
334         return contentLength;
335       }
336     }
337     return contentLength;
338   }
339 
340   public int getStatusCode() {
341     if (statusCode == SENTINEL) {
342       if (httpResponse != null) {
343         statusCode = serverAdapter.getStatusCode();
344       }
345     }
346     return statusCode;
347   }
348 
349   @SuppressWarnings("unchecked")
350   public String getRequestContent() {
351     if (requestContent != null) {
352       return requestContent;
353     }
354 
355     if (Util.isFormUrlEncoded(httpRequest)) {
356       StringBuffer buf = new StringBuffer();
357 
358       Enumeration pramEnumeration = httpRequest.getParameterNames();
359 
360       // example: id=1234&user=cgu
361       // number=1233&x=1
362       int count = 0;
363       try {
364         while (pramEnumeration.hasMoreElements()) {
365 
366           String key = (String) pramEnumeration.nextElement();
367           if (count++ != 0) {
368             buf.append("&");
369           }
370           buf.append(key);
371           buf.append("=");
372           String val = httpRequest.getParameter(key);
373           if (val != null) {
374             buf.append(val);
375           } else {
376             buf.append("");
377           }
378         }
379       } catch (Exception e) {
380         // FIXME Why is try/catch required?
381         e.printStackTrace();
382       }
383       requestContent = buf.toString();
384     } else {
385 
386       // retreive the byte array placed by TeeFilter
387       byte[] inputBuffer = (byte[]) httpRequest
388           .getAttribute(AccessConstants.LB_INPUT_BUFFER);
389 
390       if (inputBuffer != null) {
391         requestContent = new String(inputBuffer);
392       }
393 
394       if (requestContent == null || requestContent.length() == 0) {
395         requestContent = EMPTY;
396       }
397     }
398 
399     return requestContent;
400   }
401 
402   public String getResponseContent() {
403     if (responseContent != null) {
404       return responseContent;
405     }
406 
407     if (Util.isImageResponse(httpResponse)) {
408       responseContent = "[IMAGE CONTENTS SUPPRESSED]";
409     } else {
410 
411       // retreive the byte array previously placed by TeeFilter
412       byte[] outputBuffer = (byte[]) httpRequest
413           .getAttribute(AccessConstants.LB_OUTPUT_BUFFER);
414 
415       if (outputBuffer != null) {
416         responseContent = new String(outputBuffer);
417       }
418       if (responseContent == null || responseContent.length() == 0) {
419         responseContent = EMPTY;
420       }
421     }
422 
423     return responseContent;
424   }
425 
426   public int getLocalPort() {
427     if (localPort == SENTINEL) {
428       if (httpRequest != null) {
429         localPort = httpRequest.getLocalPort();
430       }
431 
432     }
433     return localPort;
434   }
435 
436   public ServerAdapter getServerAdapter() {
437     return serverAdapter;
438   }
439 
440   public String getResponseHeader(String key) {
441     buildResponseHeaderMap();
442     return responseHeaderMap.get(key);
443   }
444 
445   void buildResponseHeaderMap() {
446     if (responseHeaderMap == null) {
447       responseHeaderMap = serverAdapter.buildResponseHeaderMap();
448     }
449   }
450 
451   public Map<String, String> getResponseHeaderMap() {
452     buildResponseHeaderMap();
453     return responseHeaderMap;
454   }
455 
456   public List<String> getResponseHeaderNameList() {
457     buildResponseHeaderMap();
458     return new ArrayList<String>(responseHeaderMap.keySet());
459   }
460 
461   public void prepareForDeferredProcessing() {
462     buildRequestHeaderMap();
463     buildRequestParameterMap();
464     buildResponseHeaderMap();
465     getLocalPort();
466     getMethod();
467     getProtocol();
468     getRemoteAddr();
469     getRemoteHost();
470     getRemoteUser();
471     getRequestURI();
472     getRequestURL();
473     getServerName();
474     getTimeStamp();
475 
476     getStatusCode();
477     getContentLength();
478     getRequestContent();
479     getResponseContent();
480   }
481 }