6fe096eaa02f4437e439b00732e94aa774f1c62e
[percentcodec] / cachecontrol / src / test / java / de / halbekunst / juplo / cachecontrol / HttpTestCase.java
1 package de.halbekunst.juplo.cachecontrol;
2
3 import com.meterware.httpunit.WebResponse;
4 import com.meterware.servletunit.InvocationContext;
5 import com.meterware.servletunit.ServletRunner;
6 import com.meterware.servletunit.ServletUnitClient;
7 import java.io.IOException;
8 import java.io.PrintWriter;
9 import java.util.Enumeration;
10 import java.util.HashMap;
11 import java.util.Map;
12 import javax.servlet.ServletOutputStream;
13 import javax.servlet.http.HttpServletRequest;
14 import javax.servlet.http.HttpServletResponse;
15 import javax.servlet.http.HttpServletResponseWrapper;
16 import org.junit.Before;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 /**
21  *
22  * @author kai
23  */
24 public abstract class HttpTestCase {
25   private final static Logger log = LoggerFactory.getLogger(HttpTestCase.class);
26
27   private ServletRunner sr;
28   ServletUnitClient client;
29   int buffer = 2048;
30
31
32   @Before
33   public void init() throws Exception {
34     sr = new ServletRunner(ParameterGuessingTest.class.getResourceAsStream("/web.xml"));
35     client = sr.newClient();
36   }
37
38   protected WebResponse executeRequest(String uri) throws Exception {
39     log.debug("---------- GET: {}", uri);
40     InvocationContext invocation = client.newInvocation(uri);
41     HttpServletRequest request = invocation.getRequest();
42     log.debug("Request - {}: {}", request.getMethod(), request.getProtocol());
43     Enumeration<String> headers = request.getHeaderNames();
44     while (headers.hasMoreElements()) {
45       String header = headers.nextElement();
46       Enumeration<String> values = request.getHeaders(header);
47       while (values.hasMoreElements())
48         log.debug("Request - {}: {}", header, values.nextElement());
49     }
50     log.debug("Invocing service method.");
51
52     /**
53      * We cannot call invocation.service(), because we have to wrap the
54      * response. Therefore this was coppied from InvocationContextImpl.
55      */
56     TestHttpServletResponse wrappedResponse = new TestHttpServletResponse(invocation.getResponse());
57     if (invocation.isFilterActive()) {
58       invocation.getFilter().doFilter(invocation.getRequest(), wrappedResponse, invocation.getFilterChain());
59     }
60     else {
61       invocation.getServlet().service(invocation.getRequest(), wrappedResponse);
62     }
63
64     WebResponse response = client.getResponse(invocation);
65     log.debug("Response - {}: {}", response.getResponseCode(), response.getResponseMessage());
66     log.debug("Response - {}, {} bytes", response.getContentType(), wrappedResponse.getCount());
67     for (String header : response.getHeaderFieldNames()) {
68       for (String value : response.getHeaderFields(header)) {
69         log.debug("Response - {}: {}", header, value);
70       }
71     }
72     return response;
73   }
74
75
76   class TestHttpServletResponse extends HttpServletResponseWrapper {
77
78     private CountingServletOutputStream out;
79     private HttpServletResponse response;
80     private ServletOutputStream stream;
81     private PrintWriter writer;
82     private boolean committed = false;
83
84
85     TestHttpServletResponse(HttpServletResponse response) {
86       super(response);
87       this.response = response;
88     }
89
90
91     public long getCount() {
92       if (out == null)
93         return -1l;
94       else
95         return out.count;
96     }
97
98
99     @Override
100     public void flushBuffer() throws IOException {
101       committed = true;
102       super.flushBuffer();
103     }
104
105     @Override
106     public int getBufferSize() {
107       return buffer;
108     }
109
110     @Override
111     public boolean isCommitted() {
112       return committed;
113     }
114
115     @Override
116     public void reset() {
117       if (committed)
118         throw new IllegalStateException("call to reset() after response has been commited!");
119       if (out != null)
120         out.count = 0;
121       super.reset();
122     }
123
124     @Override
125     public void resetBuffer() {
126       if (committed)
127         throw new IllegalStateException("call to resetBuffer() after response has been commited!");
128       if (out != null)
129         out.count = 0;
130       super.resetBuffer();
131     }
132
133     @Override
134     public void setBufferSize(int size) {
135       if (out != null && out.count > 0)
136         throw new IllegalStateException("call to setBuffer() after content has been written!");
137       buffer = size;
138     }
139
140     @Override
141     public ServletOutputStream getOutputStream() throws IOException {
142
143       if (writer != null)
144         throw new IllegalStateException("ServletOutputStream and PrintWriter cannot be requested both!");
145
146       if (stream == null) {
147         out = new CountingServletOutputStream(response.getOutputStream());
148         stream = out;
149       }
150
151       return stream;
152     }
153
154     @Override
155     public PrintWriter getWriter() throws IOException {
156
157       if (stream != null)
158         throw new IllegalStateException("ServletOutputStream and PrintWriter cannot be requested both!");
159
160       if (writer == null) {
161         out = new CountingServletOutputStream(response.getOutputStream());
162         writer = new PrintWriter(out);
163       }
164
165       return writer;
166     }
167
168
169     class CountingServletOutputStream extends ServletOutputStream {
170
171       private ServletOutputStream out;
172       long count = 0l;
173
174
175       CountingServletOutputStream(ServletOutputStream out) {
176         this.out = out;
177       }
178
179
180       @Override
181       public void write(int i) throws IOException {
182         count++;
183         /** Simulate commit, when count is getting bigger then buffer */
184         if (count == buffer + 1) {
185           log.debug("simulating commit because buffer overflow! buffer: {}, count: {}", buffer, count);
186           committed = true;
187         }
188         out.write(i);
189       }
190     }
191   }
192 }
193