View Javadoc

1   package com.bradmcevoy.http;
2   
3   import java.io.ByteArrayInputStream;
4   import java.io.File;
5   import java.io.FileNotFoundException;
6   import java.io.FileOutputStream;
7   import java.io.IOException;
8   import java.io.InputStream;
9   import java.io.OutputStream;
10  import java.io.PrintWriter;
11  import java.util.List;
12  import java.util.Map;
13  
14  import org.apache.commons.io.output.ByteArrayOutputStream;
15  
16  import org.slf4j.Logger;
17  import org.slf4j.LoggerFactory;
18  
19  import com.bradmcevoy.io.StreamUtils;
20  
21  /**
22   *
23   */
24  public class DebugFilter implements Filter{
25  
26      private static final Logger log = LoggerFactory.getLogger(DebugFilter.class);
27  
28      private static int counter = 0;
29  
30      private File logDir;
31  
32      public DebugFilter() {
33          logDir = new File(System.getProperty("user.home"));
34          log.debug( "logging to: " + logDir.getAbsolutePath());
35      }
36  
37      public DebugFilter( File logDir ) {
38          this.logDir = logDir;
39          log.debug( "logging to: " + logDir.getAbsolutePath());
40      }
41  
42  
43  
44      public void process(FilterChain chain, Request request, Response response) {
45          try {
46              DebugRequest req2 = new DebugRequest(request);
47              DebugResponse resp2 = new DebugResponse(response);
48              chain.process(req2, resp2);
49              record(req2,resp2);
50              response.getOutputStream().write(resp2.out.toByteArray());
51              response.getOutputStream().flush();
52          } catch (IOException ex) {
53              log.error("", ex);
54          }
55      }
56  
57      private synchronized void record(DebugRequest req2, DebugResponse resp2) {
58          counter++;
59          FileOutputStream fout = null;
60          try {
61              File f = new File(logDir, counter + "_" + req2.getMethod() + ".req");
62              fout = new FileOutputStream(f);
63              req2.record(fout);
64          } catch (FileNotFoundException ex) {
65              throw new RuntimeException(ex);
66          } finally {
67              StreamUtils.close( fout );
68          }
69  
70          try {
71              File f = new File(logDir, counter + "_" + resp2.getStatus().code + ".resp");
72              fout = new FileOutputStream(f);
73              resp2.record(fout);
74          } catch (FileNotFoundException ex) {
75              throw new RuntimeException(ex);
76          } finally {
77              StreamUtils.close( fout );
78          }
79  
80      }
81  
82      public class DebugResponse extends AbstractResponse {
83          final Response r;
84          final ByteArrayOutputStream out;
85          List<String> challenges;
86  
87          public DebugResponse(Response r) {
88              this.r = r;
89              out = new ByteArrayOutputStream();
90          }
91  
92          public Status getStatus() {
93              return r.getStatus();
94          }
95  
96          public void setStatus(Status status) {
97              r.setStatus(status);
98          }
99  
100         public void setNonStandardHeader(String code, String value) {
101             r.setNonStandardHeader(code, value);
102         }
103 
104         public String getNonStandardHeader(String code) {
105             return r.getNonStandardHeader(code);
106         }
107 
108         public OutputStream getOutputStream() {
109             return out;
110         }
111 
112         public  Map<String,String> getHeaders() {
113             return r.getHeaders();
114         }
115 
116         private void record(FileOutputStream fout) {
117             try {
118                 PrintWriter writer = new PrintWriter(fout);
119                 if( getStatus() != null ) {
120                     writer.println("HTTP/1.1 " + getStatus().code);
121                 }
122                 for (Map.Entry<String, String> header : this.getHeaders().entrySet()) {
123                     writer.println(header.getKey() + ": " + header.getValue());
124                 }
125                 if( challenges != null ) {
126                     for( String ch : challenges) {
127                         writer.println(Response.Header.WWW_AUTHENTICATE + ": " + ch);
128                     }
129                 }
130                 writer.flush();
131                 
132                 // write to console
133                 log.debug( out.toString());
134 
135                 fout.write(out.toByteArray());
136                 fout.flush();
137             } catch (IOException ex) {
138                 log.error("",ex);
139             }
140         }
141 
142         public void setAuthenticateHeader( List<String> challenges ) {
143             this.challenges = challenges;
144             r.setAuthenticateHeader( challenges );
145         }
146 
147         public Cookie setCookie( Cookie cookie ) {
148             return r.setCookie( cookie );
149         }
150 
151         public Cookie setCookie( String name, String value ) {
152             return r.setCookie( name, value );
153         }
154 
155 
156     }
157 
158     public class DebugRequest extends AbstractRequest {
159         final Request r;
160         final byte[] contentBytes;
161         final ByteArrayInputStream content;
162 
163         public DebugRequest(Request r) {
164             this.r = r;
165             ByteArrayOutputStream out = new ByteArrayOutputStream();
166             try {
167                 StreamUtils.readTo(r.getInputStream(), out);
168             } catch (IOException ex) {
169                 throw new RuntimeException(ex);
170             }
171             this.contentBytes = out.toByteArray();
172             this.content = new ByteArrayInputStream(this.contentBytes);
173             log.debug(out.toString());
174         }
175 
176         public Map<String, String> getHeaders() {
177             return r.getHeaders();
178         }
179 
180         @Override
181         public String getRequestHeader(Header header) {
182             return r.getRequestHeader(header);
183         }
184 
185         public String getFromAddress() {
186             return r.getFromAddress();
187         }
188 
189         public Method getMethod() {
190             return r.getMethod();
191         }
192 
193         public Auth getAuthorization() {
194             return r.getAuthorization();
195         }
196 
197         public void setAuthorization( Auth auth ) {
198             r.setAuthorization( auth );
199         }
200 
201 
202 
203         public String getAbsoluteUrl() {
204             return r.getAbsoluteUrl();
205         }
206 
207         public InputStream getInputStream() throws IOException {
208             return content;
209         }
210 
211         public void parseRequestParameters(Map<String, String> params, Map<String, FileItem> files) throws RequestParseException {
212             r.parseRequestParameters(params, files);
213         }
214 
215         public void record(OutputStream out) {
216             PrintWriter writer = new PrintWriter(out);
217             writer.println(getMethod() + " " + getAbsolutePath() + " HTTP/1.1");
218             for(Map.Entry<String,String> header : this.getHeaders().entrySet()) {
219                 writer.println(header.getKey() + ": " + header.getValue());
220             }
221             writer.flush();
222             try {
223                 out.write(contentBytes);
224             } catch (IOException ex) {
225                 log.error("",ex);
226             }
227         }
228 
229         public Cookie getCookie( String name ) {
230             return r.getCookie( name );
231         }
232 
233         public List<Cookie> getCookies() {
234             return r.getCookies();
235         }
236 
237         public String getRemoteAddr() {
238             return r.getRemoteAddr();
239         }
240 
241     }
242 
243 }