001: /*
002: * ====================================================================
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: * ====================================================================
019: *
020: * This software consists of voluntary contributions made by many
021: * individuals on behalf of the Apache Software Foundation. For more
022: * information on the Apache Software Foundation, please see
023: * <http://www.apache.org/>.
024: *
025: * [Additional notices, if required by prior licensing conditions]
026: *
027: */
028: package org.apache.commons.httpclient;
029:
030: import java.io.IOException;
031:
032: import junit.framework.*;
033: import org.apache.commons.httpclient.methods.*;
034: import org.apache.commons.httpclient.params.HttpMethodParams;
035: import org.apache.commons.httpclient.server.HttpRequestHandler;
036: import org.apache.commons.httpclient.server.ResponseWriter;
037: import org.apache.commons.httpclient.server.SimpleHttpServerConnection;
038: import org.apache.commons.httpclient.server.SimpleRequest;
039:
040: /**
041: * Tests handling of non-compliant responses.
042: *
043: * @author Oleg Kalnichevski
044: * @author Jeff Dever
045: */
046: public class TestNoncompliant extends HttpClientTestBase {
047:
048: public TestNoncompliant(String s) throws IOException {
049: super (s);
050: }
051:
052: public static Test suite() {
053: TestSuite suite = new TestSuite(TestNoncompliant.class);
054: return suite;
055: }
056:
057: /**
058: * Tests if client is able to recover gracefully when HTTP server or
059: * proxy fails to send 100 status code when expected. The client should
060: * resume sending the request body after a defined timeout without having
061: * received "continue" code.
062: */
063: public void testNoncompliantPostMethodString() throws Exception {
064: this .server.setRequestHandler(new HttpRequestHandler() {
065: public boolean processRequest(
066: SimpleHttpServerConnection conn,
067: SimpleRequest request) throws IOException {
068: ResponseWriter out = conn.getWriter();
069: out.println("HTTP/1.1 200 OK");
070: out.println("Connection: close");
071: out.println("Content-Length: 0");
072: out.println();
073: out.flush();
074: return true;
075: }
076: });
077:
078: PostMethod method = new PostMethod("/");
079: method.getParams().setBooleanParameter(
080: HttpMethodParams.USE_EXPECT_CONTINUE, true);
081: method.setRequestEntity(new StringRequestEntity(
082: "This is data to be sent in the body of an HTTP POST.",
083: null, null));
084: client.executeMethod(method);
085: assertEquals(200, method.getStatusCode());
086: }
087:
088: /**
089: * Tests that a response status line containing \r and \n is handled.
090: */
091: public void testNoncompliantStatusLine() {
092: this .server.setRequestHandler(new HttpRequestHandler() {
093: public boolean processRequest(
094: SimpleHttpServerConnection conn,
095: SimpleRequest request) throws IOException {
096: ResponseWriter out = conn.getWriter();
097: out
098: .println("HTTP/1.1 444 This status message contains\n"
099: + " a newline and a\r"
100: + " carrage return but that should be OK.");
101: out.println("Connection: close");
102: out.println("Content-Length: 0");
103: out.println();
104: out.flush();
105: return true;
106: }
107: });
108: GetMethod method = new GetMethod("/");
109: try {
110: client.executeMethod(method);
111: } catch (Exception e) {
112: e.printStackTrace();
113: fail("Unexpected exception: " + e.toString());
114: }
115: assertEquals(444, method.getStatusCode());
116: }
117:
118: /**
119: * Test if a response to HEAD method from non-compliant server that contains
120: * an unexpected body content can be correctly redirected
121: */
122: public void testNoncompliantHeadWithResponseBody() throws Exception {
123: final String body = "Test body";
124: this .server.setRequestHandler(new HttpRequestHandler() {
125: public boolean processRequest(
126: SimpleHttpServerConnection conn,
127: SimpleRequest request) throws IOException {
128: ResponseWriter out = conn.getWriter();
129: out.println("HTTP/1.1 200 OK");
130: out.println("Connection: close");
131: out.println("Content-Length: " + body.length());
132: out.println();
133: out.print(body);
134: out.flush();
135: return true;
136: }
137: });
138: HeadMethod method = new HeadMethod("/");
139: method.getParams().setIntParameter(
140: HttpMethodParams.HEAD_BODY_CHECK_TIMEOUT, 50);
141: client.executeMethod(method);
142: assertEquals(200, method.getStatusCode());
143: method.releaseConnection();
144: }
145:
146: /**
147: * Test if a response to HEAD method from non-compliant server causes an
148: * HttpException to be thrown
149: */
150: public void testNoncompliantHeadStrictMode() throws Exception {
151: final String body = "Test body";
152: this .server.setRequestHandler(new HttpRequestHandler() {
153: public boolean processRequest(
154: SimpleHttpServerConnection conn,
155: SimpleRequest request) throws IOException {
156: ResponseWriter out = conn.getWriter();
157: out.println("HTTP/1.1 200 OK");
158: out.println("Connection: close");
159: out.println("Content-Length: " + body.length());
160: out.println();
161: out.print(body);
162: out.flush();
163: return true;
164: }
165: });
166: client.getParams().setBooleanParameter(
167: HttpMethodParams.REJECT_HEAD_BODY, true);
168: HeadMethod method = new NoncompliantHeadMethod("/");
169: method.getParams().setIntParameter(
170: HttpMethodParams.HEAD_BODY_CHECK_TIMEOUT, 50);
171: try {
172: client.executeMethod(method);
173: fail("HttpException should have been thrown");
174: } catch (HttpException e) {
175: // Expected
176: }
177: method.releaseConnection();
178: }
179:
180: /**
181: * Tests if client is able to handle gracefully malformed responses
182: * that may not include response body.
183: */
184: public void testMalformed304Response() throws Exception {
185: this .server.setRequestHandler(new HttpRequestHandler() {
186: public boolean processRequest(
187: SimpleHttpServerConnection conn,
188: SimpleRequest request) throws IOException {
189: conn.setSocketTimeout(20000);
190: ResponseWriter out = conn.getWriter();
191: out.println("HTTP/1.1 304 OK");
192: out.println("Connection: keep-alive");
193: out.println("Content-Length: 100");
194: out.println();
195: out.flush();
196: conn.setKeepAlive(true);
197: return true;
198: }
199: });
200:
201: GetMethod method = new GetMethod("/");
202: method.getParams().setSoTimeout(1000);
203: client.executeMethod(method);
204: assertEquals(HttpStatus.SC_NOT_MODIFIED, method.getStatusCode());
205: method.getResponseBody();
206: }
207:
208: public void testMalformed204Response() throws Exception {
209: this .server.setRequestHandler(new HttpRequestHandler() {
210: public boolean processRequest(
211: SimpleHttpServerConnection conn,
212: SimpleRequest request) throws IOException {
213: conn.setSocketTimeout(20000);
214: ResponseWriter out = conn.getWriter();
215: out.println("HTTP/1.1 204 OK");
216: out.println("Connection: close");
217: out.println("Content-Length: 100");
218: out.println();
219: out.flush();
220: conn.setKeepAlive(true);
221: return true;
222: }
223: });
224:
225: GetMethod method = new GetMethod("/");
226: method.getParams().setSoTimeout(1000);
227: client.executeMethod(method);
228: assertEquals(HttpStatus.SC_NO_CONTENT, method.getStatusCode());
229: method.getResponseBody();
230: }
231:
232: }
|