1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.commons.httpclient;
29
30 import java.io.IOException;
31 import java.io.InputStream;
32
33 import junit.framework.Test;
34 import junit.framework.TestCase;
35 import junit.framework.TestSuite;
36
37 import org.apache.commons.httpclient.methods.GetMethod;
38 import org.apache.commons.httpclient.server.HttpRequestHandler;
39 import org.apache.commons.httpclient.server.RequestLine;
40 import org.apache.commons.httpclient.server.ResponseWriter;
41 import org.apache.commons.httpclient.server.SimpleHttpServer;
42 import org.apache.commons.httpclient.server.SimpleHttpServerConnection;
43 import org.apache.commons.httpclient.server.SimpleRequest;
44
45 /***
46 * Tests HttpClient's behaviour when receiving more response data than expected.
47 * <p>
48 * A very simple HTTP Server will be setup on a free port during testing, which
49 * returns an incorrect response Content-Length, sending surplus response data,
50 * which may contain malicious/fake response headers.
51 * </p>
52 *
53 * @author Christian Kohlschuetter
54 * @version $Id: TestBadContentLength.java 201862 2005-06-26 15:03:07Z olegk $
55 */
56 public class TestBadContentLength extends TestCase {
57 private HttpClient client = null;
58 private SimpleHttpServer server = null;
59
60
61 public TestBadContentLength(String testName) {
62 super(testName);
63 }
64
65
66 public static void main(String args[]) {
67 String[] testCaseName = { TestBadContentLength.class.getName()};
68 junit.textui.TestRunner.main(testCaseName);
69 }
70
71
72
73 public static Test suite() {
74 return new TestSuite(TestBadContentLength.class);
75 }
76
77
78
79 public void setUp() throws IOException {
80 client = new HttpClient();
81 server = new SimpleHttpServer();
82 server.setTestname(getName());
83 server.setRequestHandler(new MyHttpRequestHandler());
84 }
85
86 public void tearDown() throws IOException {
87 client = null;
88
89 server.destroy();
90 }
91
92 /***
93 * HttpClient connects to the test server and performs two subsequent
94 * requests to the same URI in <u>lenient</u> mode.
95 *
96 * Expected behavior:
97 * For both requests, status code 200 and a response body of "12345"
98 * should be returned.
99 *
100 * @throws IOException
101 */
102 public void test1Lenient() throws IOException {
103 client.getParams().makeLenient();
104
105 GetMethod m =
106 new GetMethod("http://localhost:" + server.getLocalPort() + "/");
107
108 client.executeMethod(m);
109 assertEquals(200, m.getStatusCode());
110 assertEquals("12345", m.getResponseBodyAsString());
111
112 m = new GetMethod("http://localhost:" + server.getLocalPort() + "/");
113
114 client.executeMethod(m);
115 assertEquals(200, m.getStatusCode());
116 assertEquals("12345", m.getResponseBodyAsString());
117 m.releaseConnection();
118 }
119
120 /***
121 * HttpClient connects to the test server and performs two subsequent
122 * requests to the same URI in <u>strict</u> mode.
123 * <p>
124 * The first response body will be read with getResponseBodyAsString(),
125 * which returns null if an error occured.
126 * </p>
127 * <p>
128 * The second response body will be read using an InputStream, which
129 * throws an IOException if something went wrong.
130 * </p>
131 * Expected behavior:
132 * For both requests, status code 200 should be returned.<br />
133 * For request 1, a <code>null</code> response body should be returned.<br />
134 * For request 2, a {@link ProtocolException} is expected.
135 *
136 * @throws IOException
137 */
138 public void test1Strict() throws IOException {
139 client.getParams().makeStrict();
140
141 GetMethod m =
142 new GetMethod("http://localhost:" + server.getLocalPort() + "/");
143
144 client.executeMethod(m);
145 assertEquals(200, m.getStatusCode());
146 assertEquals("12345", m.getResponseBodyAsString());
147
148 m = new GetMethod("http://localhost:" + server.getLocalPort() + "/");
149
150 client.executeMethod(m);
151 assertEquals(200, m.getStatusCode());
152
153 InputStream in = m.getResponseBodyAsStream();
154 while (in.read() != -1) {
155 }
156
157 m.releaseConnection();
158 }
159
160 public void enableThisTestForDebuggingOnly()
161 throws InterruptedException {
162 while (server.isRunning()) {
163 Thread.sleep(100);
164 }
165 }
166
167 private class MyHttpRequestHandler implements HttpRequestHandler {
168 private int requestNo = 0;
169
170 public boolean processRequest(
171 final SimpleHttpServerConnection conn,
172 final SimpleRequest request) throws IOException
173 {
174 RequestLine requestLine = request.getRequestLine();
175 ResponseWriter out = conn.getWriter();
176 if ("GET".equals(requestLine.getMethod())
177 && "/".equals(requestLine.getUri())) {
178
179 requestNo++;
180
181 out.println("HTTP/1.1 200 OK");
182 out.println("Content-Type: text/html");
183 out.println("Content-Length: 5");
184 out.println("Connection: keep-alive");
185 out.println();
186 out.println("12345");
187
188
189 out.println("AND SOME MORE\r\nGARBAGE!");
190 out.println("HTTP/1.0 404 Not Found");
191 out.println("Content-Type: text/plain");
192 out.println("");
193 out.println("THIS-IS-A-FAKE-RESPONSE!");
194
195 out.flush();
196
197 if (requestNo < 2) {
198 conn.setKeepAlive(true);
199 }
200 }
201 return true;
202 }
203 }
204
205 }