001: /*
002: * $HeadURL: https://svn.apache.org/repos/asf/jakarta/httpcomponents/oac.hc3x/tags/HTTPCLIENT_3_1/src/test/org/apache/commons/httpclient/TestBadContentLength.java $
003: * $Revision: 480424 $
004: * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
005: * ====================================================================
006: *
007: * Licensed to the Apache Software Foundation (ASF) under one or more
008: * contributor license agreements. See the NOTICE file distributed with
009: * this work for additional information regarding copyright ownership.
010: * The ASF licenses this file to You under the Apache License, Version 2.0
011: * (the "License"); you may not use this file except in compliance with
012: * the License. You may obtain a copy of the License at
013: *
014: * http://www.apache.org/licenses/LICENSE-2.0
015: *
016: * Unless required by applicable law or agreed to in writing, software
017: * distributed under the License is distributed on an "AS IS" BASIS,
018: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019: * See the License for the specific language governing permissions and
020: * limitations under the License.
021: * ====================================================================
022: *
023: * This software consists of voluntary contributions made by many
024: * individuals on behalf of the Apache Software Foundation. For more
025: * information on the Apache Software Foundation, please see
026: * <http://www.apache.org/>.
027: *
028: */
029: package org.apache.commons.httpclient;
030:
031: import java.io.IOException;
032: import java.io.InputStream;
033:
034: import junit.framework.Test;
035: import junit.framework.TestCase;
036: import junit.framework.TestSuite;
037:
038: import org.apache.commons.httpclient.methods.GetMethod;
039: import org.apache.commons.httpclient.server.HttpRequestHandler;
040: import org.apache.commons.httpclient.server.RequestLine;
041: import org.apache.commons.httpclient.server.ResponseWriter;
042: import org.apache.commons.httpclient.server.SimpleHttpServer;
043: import org.apache.commons.httpclient.server.SimpleHttpServerConnection;
044: import org.apache.commons.httpclient.server.SimpleRequest;
045:
046: /**
047: * Tests HttpClient's behaviour when receiving more response data than expected.
048: * <p>
049: * A very simple HTTP Server will be setup on a free port during testing, which
050: * returns an incorrect response Content-Length, sending surplus response data,
051: * which may contain malicious/fake response headers.
052: * </p>
053: *
054: * @author Christian Kohlschuetter
055: * @version $Id: TestBadContentLength.java 480424 2006-11-29 05:56:49Z bayard $
056: */
057: public class TestBadContentLength extends TestCase {
058: private HttpClient client = null;
059: private SimpleHttpServer server = null;
060:
061: // ------------------------------------------------------------ Constructor
062: public TestBadContentLength(String testName) {
063: super (testName);
064: }
065:
066: // ------------------------------------------------------------------- Main
067: public static void main(String args[]) {
068: String[] testCaseName = { TestBadContentLength.class.getName() };
069: junit.textui.TestRunner.main(testCaseName);
070: }
071:
072: // ------------------------------------------------------- TestCase Methods
073:
074: public static Test suite() {
075: return new TestSuite(TestBadContentLength.class);
076: }
077:
078: // ----------------------------------------------------------- Test Methods
079:
080: public void setUp() throws IOException {
081: client = new HttpClient();
082: server = new SimpleHttpServer(); // use arbitrary port
083: server.setTestname(getName());
084: server.setRequestHandler(new MyHttpRequestHandler());
085: }
086:
087: public void tearDown() throws IOException {
088: client = null;
089:
090: server.destroy();
091: }
092:
093: /**
094: * HttpClient connects to the test server and performs two subsequent
095: * requests to the same URI in <u>lenient</u> mode.
096: *
097: * Expected behavior:
098: * For both requests, status code 200 and a response body of "12345"
099: * should be returned.
100: *
101: * @throws IOException
102: */
103: public void test1Lenient() throws IOException {
104: client.getParams().makeLenient();
105:
106: GetMethod m = new GetMethod("http://localhost:"
107: + server.getLocalPort() + "/");
108:
109: client.executeMethod(m);
110: assertEquals(200, m.getStatusCode());
111: assertEquals("12345", m.getResponseBodyAsString());
112:
113: m = new GetMethod("http://localhost:" + server.getLocalPort()
114: + "/");
115:
116: client.executeMethod(m);
117: assertEquals(200, m.getStatusCode());
118: assertEquals("12345", m.getResponseBodyAsString());
119: m.releaseConnection();
120: }
121:
122: /**
123: * HttpClient connects to the test server and performs two subsequent
124: * requests to the same URI in <u>strict</u> mode.
125: * <p>
126: * The first response body will be read with getResponseBodyAsString(),
127: * which returns null if an error occured.
128: * </p>
129: * <p>
130: * The second response body will be read using an InputStream, which
131: * throws an IOException if something went wrong.
132: * </p>
133: * Expected behavior:
134: * For both requests, status code 200 should be returned.<br />
135: * For request 1, a <code>null</code> response body should be returned.<br />
136: * For request 2, a {@link ProtocolException} is expected.
137: *
138: * @throws IOException
139: */
140: public void test1Strict() throws IOException {
141: client.getParams().makeStrict();
142:
143: GetMethod m = new GetMethod("http://localhost:"
144: + server.getLocalPort() + "/");
145:
146: client.executeMethod(m);
147: assertEquals(200, m.getStatusCode());
148: assertEquals("12345", m.getResponseBodyAsString());
149:
150: m = new GetMethod("http://localhost:" + server.getLocalPort()
151: + "/");
152:
153: client.executeMethod(m);
154: assertEquals(200, m.getStatusCode());
155:
156: InputStream in = m.getResponseBodyAsStream();
157: while (in.read() != -1) {
158: }
159:
160: m.releaseConnection();
161: }
162:
163: public void enableThisTestForDebuggingOnly()
164: throws InterruptedException {
165: while (server.isRunning()) {
166: Thread.sleep(100);
167: }
168: }
169:
170: private class MyHttpRequestHandler implements HttpRequestHandler {
171: private int requestNo = 0;
172:
173: public boolean processRequest(
174: final SimpleHttpServerConnection conn,
175: final SimpleRequest request) throws IOException {
176: RequestLine requestLine = request.getRequestLine();
177: ResponseWriter out = conn.getWriter();
178: if ("GET".equals(requestLine.getMethod())
179: && "/".equals(requestLine.getUri())) {
180:
181: requestNo++;
182:
183: out.println("HTTP/1.1 200 OK");
184: out.println("Content-Type: text/html");
185: out.println("Content-Length: 5");
186: out.println("Connection: keep-alive");
187: out.println();
188: out.println("12345"); // send exactly 5 bytes
189:
190: // and some more garbage!
191: out.println("AND SOME MORE\r\nGARBAGE!");
192: out.println("HTTP/1.0 404 Not Found");
193: out.println("Content-Type: text/plain");
194: out.println("");
195: out.println("THIS-IS-A-FAKE-RESPONSE!");
196:
197: out.flush();
198: // process max. 2 subsequents requests per connection
199: if (requestNo < 2) {
200: conn.setKeepAlive(true);
201: }
202: }
203: return true;
204: }
205: }
206:
207: }
|