1   /*
2    * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/oac.hc3x/trunk/src/test/org/apache/commons/httpclient/TestEntityEnclosingMethod.java $
3    * $Revision: 1425331 $
4    * $Date: 2012-12-22 18:29:41 +0000 (Sat, 22 Dec 2012) $
5    *
6    * ====================================================================
7    *
8    *  Licensed to the Apache Software Foundation (ASF) under one or more
9    *  contributor license agreements.  See the NOTICE file distributed with
10   *  this work for additional information regarding copyright ownership.
11   *  The ASF licenses this file to You under the Apache License, Version 2.0
12   *  (the "License"); you may not use this file except in compliance with
13   *  the License.  You may obtain a copy of the License at
14   *
15   *      http://www.apache.org/licenses/LICENSE-2.0
16   *
17   *  Unless required by applicable law or agreed to in writing, software
18   *  distributed under the License is distributed on an "AS IS" BASIS,
19   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   *  See the License for the specific language governing permissions and
21   *  limitations under the License.
22   * ====================================================================
23   *
24   * This software consists of voluntary contributions made by many
25   * individuals on behalf of the Apache Software Foundation.  For more
26   * information on the Apache Software Foundation, please see
27   * <http://www.apache.org/>.
28   *
29   */
30  
31  package org.apache.commons.httpclient;
32  
33  import java.io.ByteArrayInputStream;
34  import java.io.IOException;
35  import java.io.InputStream;
36  
37  import junit.framework.Test;
38  import junit.framework.TestSuite;
39  
40  import org.apache.commons.httpclient.auth.AuthScope;
41  import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
42  import org.apache.commons.httpclient.methods.PostMethod;
43  import org.apache.commons.httpclient.methods.RequestEntity;
44  import org.apache.commons.httpclient.methods.StringRequestEntity;
45  import org.apache.commons.httpclient.server.AuthRequestHandler;
46  import org.apache.commons.httpclient.server.HttpRequestHandlerChain;
47  import org.apache.commons.httpclient.server.HttpService;
48  import org.apache.commons.httpclient.server.HttpServiceHandler;
49  import org.apache.commons.httpclient.server.SimpleRequest;
50  import org.apache.commons.httpclient.server.SimpleResponse;
51  
52  /***
53   * Tests specific to entity enclosing methods.
54   *
55   * @author Oleg Kalnichevski
56   * @version $Id: TestEntityEnclosingMethod.java 480424 2006-11-29 05:56:49Z bayard $
57   */
58  public class TestEntityEnclosingMethod extends HttpClientTestBase {
59  
60      public TestEntityEnclosingMethod(String testName) throws IOException {
61          super(testName);
62      }
63  
64      public static Test suite() {
65          TestSuite suite = new TestSuite(TestEntityEnclosingMethod.class);
66          return suite;
67      }
68  
69      public static void main(String args[]) {
70          String[] testCaseName = { TestEntityEnclosingMethod.class.getName() };
71          junit.textui.TestRunner.main(testCaseName);
72      }
73  
74      // ------------------------------------------------------------------ Tests
75      
76      public void testEnclosedEntityAutoLength() throws Exception {
77          String inputstr = "This is a test message";
78          byte[] input = inputstr.getBytes("US-ASCII");
79          InputStream instream = new ByteArrayInputStream(input);
80          
81          RequestEntity requestentity = new InputStreamRequestEntity(
82                  instream, InputStreamRequestEntity.CONTENT_LENGTH_AUTO); 
83          PostMethod method = new PostMethod("/");
84          method.setRequestEntity(requestentity);
85          this.server.setHttpService(new EchoService());
86          try {
87              this.client.executeMethod(method);
88              assertEquals(200, method.getStatusCode());
89              String body = method.getResponseBodyAsString();
90              assertEquals(inputstr, body);
91              assertNull(method.getRequestHeader("Transfer-Encoding"));
92              assertNotNull(method.getRequestHeader("Content-Length"));
93              assertEquals(input.length, Integer.parseInt(
94                      method.getRequestHeader("Content-Length").getValue()));
95          } finally {
96              method.releaseConnection();
97          }
98      }
99  
100     public void testEnclosedEntityExplicitLength() throws Exception {
101         String inputstr = "This is a test message";
102         byte[] input = inputstr.getBytes("US-ASCII");
103         InputStream instream = new ByteArrayInputStream(input);
104         
105         RequestEntity requestentity = new InputStreamRequestEntity(
106                 instream, 14); 
107         PostMethod method = new PostMethod("/");
108         method.setRequestEntity(requestentity);
109         this.server.setHttpService(new EchoService());
110         try {
111             this.client.executeMethod(method);
112             assertEquals(200, method.getStatusCode());
113             String body = method.getResponseBodyAsString();
114             assertEquals("This is a test", body);
115             assertNull(method.getRequestHeader("Transfer-Encoding"));
116             assertNotNull(method.getRequestHeader("Content-Length"));
117             assertEquals(14, Integer.parseInt(
118                     method.getRequestHeader("Content-Length").getValue()));
119         } finally {
120             method.releaseConnection();
121         }
122     }
123 
124     public void testEnclosedEntityChunked() throws Exception {
125         String inputstr = "This is a test message";
126         byte[] input = inputstr.getBytes("US-ASCII");
127         InputStream instream = new ByteArrayInputStream(input);
128         
129         RequestEntity requestentity = new InputStreamRequestEntity(
130                 instream, InputStreamRequestEntity.CONTENT_LENGTH_AUTO); 
131         PostMethod method = new PostMethod("/");
132         method.setRequestEntity(requestentity);
133         method.setContentChunked(true);
134         this.server.setHttpService(new EchoService());
135         try {
136             this.client.executeMethod(method);
137             assertEquals(200, method.getStatusCode());
138             String body = method.getResponseBodyAsString();
139             assertEquals(inputstr, body);
140             assertNotNull(method.getRequestHeader("Transfer-Encoding"));
141             assertNull(method.getRequestHeader("Content-Length"));
142         } finally {
143             method.releaseConnection();
144         }
145     }
146     
147     public void testEnclosedEntityChunkedHTTP1_0() throws Exception {
148         String inputstr = "This is a test message";
149         byte[] input = inputstr.getBytes("US-ASCII");
150         InputStream instream = new ByteArrayInputStream(input);
151         
152         RequestEntity requestentity = new InputStreamRequestEntity(
153                 instream, InputStreamRequestEntity.CONTENT_LENGTH_AUTO); 
154         PostMethod method = new PostMethod("/");
155         method.setRequestEntity(requestentity);
156         method.setContentChunked(true);
157         method.getParams().setVersion(HttpVersion.HTTP_1_0);
158         this.server.setHttpService(new EchoService());
159         try {
160             this.client.executeMethod(method);
161             fail("ProtocolException should have been thrown");
162         } catch (ProtocolException ex) {
163             // expected
164         } finally {
165             method.releaseConnection();
166         }
167     }
168 
169     public void testEnclosedEntityRepeatable() throws Exception {
170         String inputstr = "This is a test message";
171         byte[] input = inputstr.getBytes("US-ASCII");
172         InputStream instream = new ByteArrayInputStream(input);
173         
174         RequestEntity requestentity = new InputStreamRequestEntity(
175                 instream, InputStreamRequestEntity.CONTENT_LENGTH_AUTO); 
176         PostMethod method = new PostMethod("/");
177         method.setRequestEntity(requestentity);
178 
179         UsernamePasswordCredentials creds = 
180             new UsernamePasswordCredentials("testuser", "testpass");
181         
182         HttpRequestHandlerChain handlerchain = new HttpRequestHandlerChain();
183         handlerchain.appendHandler(new AuthRequestHandler(creds));
184         handlerchain.appendHandler(new HttpServiceHandler(new EchoService()));
185         this.server.setRequestHandler(handlerchain);
186         this.client.getState().setCredentials(AuthScope.ANY, creds);
187         try {
188             this.client.executeMethod(method);
189             assertEquals(200, method.getStatusCode());
190             String body = method.getResponseBodyAsString();
191             assertEquals(inputstr, body);
192             assertNull(method.getRequestHeader("Transfer-Encoding"));
193             assertNotNull(method.getRequestHeader("Content-Length"));
194             assertEquals(input.length, Integer.parseInt(
195                     method.getRequestHeader("Content-Length").getValue()));
196         } finally {
197             method.releaseConnection();
198         }
199     }
200 
201     public void testEnclosedEntityNonRepeatable() throws Exception {
202         String inputstr = "This is a test message";
203         byte[] input = inputstr.getBytes("US-ASCII");
204         InputStream instream = new ByteArrayInputStream(input);
205         
206         RequestEntity requestentity = new InputStreamRequestEntity(
207                 instream, InputStreamRequestEntity.CONTENT_LENGTH_AUTO); 
208         PostMethod method = new PostMethod("/");
209         method.setRequestEntity(requestentity);
210         method.setContentChunked(true);
211 
212         UsernamePasswordCredentials creds = 
213             new UsernamePasswordCredentials("testuser", "testpass");
214         
215         HttpRequestHandlerChain handlerchain = new HttpRequestHandlerChain();
216         handlerchain.appendHandler(new AuthRequestHandler(creds));
217         handlerchain.appendHandler(new HttpServiceHandler(new EchoService()));
218         this.server.setRequestHandler(handlerchain);
219         this.client.getState().setCredentials(AuthScope.ANY, creds);
220         try {
221             this.client.executeMethod(method);
222             fail("ProtocolException should have been thrown");
223         } catch (ProtocolException ex) {
224             // expected
225         } finally {
226             method.releaseConnection();
227         }
228     }
229     
230     public void testEnclosedEntityNegativeLength() throws Exception {
231         
232         String inputstr = "This is a test message";
233         byte[] input = inputstr.getBytes("US-ASCII");
234         InputStream instream = new ByteArrayInputStream(input);
235         
236         RequestEntity requestentity = new InputStreamRequestEntity(
237                 instream, -14); 
238         PostMethod method = new PostMethod("/");
239         method.setRequestEntity(requestentity);
240         method.setContentChunked(false);
241         this.server.setHttpService(new EchoService());
242         try {
243             this.client.executeMethod(method);
244             assertEquals(200, method.getStatusCode());
245             String body = method.getResponseBodyAsString();
246             assertEquals(inputstr, body);
247             assertNotNull(method.getRequestHeader("Transfer-Encoding"));
248             assertNull(method.getRequestHeader("Content-Length"));
249         } finally {
250             method.releaseConnection();
251         }
252     }
253 
254     public void testEnclosedEntityNegativeLengthHTTP1_0() throws Exception {
255         
256         String inputstr = "This is a test message";
257         byte[] input = inputstr.getBytes("US-ASCII");
258         InputStream instream = new ByteArrayInputStream(input);
259         
260         RequestEntity requestentity = new InputStreamRequestEntity(
261                 instream, -14); 
262         PostMethod method = new PostMethod("/");
263         method.setRequestEntity(requestentity);
264         method.setContentChunked(false);
265         method.getParams().setVersion(HttpVersion.HTTP_1_0);
266         this.server.setHttpService(new EchoService());
267         try {
268             this.client.executeMethod(method);
269             fail("ProtocolException should have been thrown");
270         } catch (ProtocolException ex) {
271             // expected
272         } finally {
273             method.releaseConnection();
274         }
275     }
276     
277     class RequestBodyStatsService implements HttpService {
278 
279         public RequestBodyStatsService() {
280             super();
281         }
282 
283         public boolean process(final SimpleRequest request, final SimpleResponse response)
284             throws IOException
285         {
286             HttpVersion httpversion = request.getRequestLine().getHttpVersion();
287             response.setStatusLine(httpversion, HttpStatus.SC_OK);
288             response.addHeader(new Header("Content-Type", "text/plain"));            
289 
290             StringBuffer buffer = new StringBuffer();
291             buffer.append("Request bosy stats:\r\n");
292             buffer.append("===================\r\n");
293             long l = request.getContentLength();
294             if (l >= 0) {
295                 buffer.append("Content-Length: ");
296                 buffer.append(l);
297                 buffer.append("\r\n");
298             }
299             Header te = request.getFirstHeader("Transfer-Encoding");
300             if (te != null) {
301                 buffer.append("Content-Length: ");
302                 buffer.append(te.getValue());
303                 buffer.append("\r\n");
304             }
305             byte[] b = request.getBodyBytes();
306             if (b.length <= 0) {
307                 buffer.append("No body submitted\r\n");
308             }
309             response.setBodyString(buffer.toString());
310             return true;
311         }
312     }
313 	
314     public void testEmptyPostMethod() throws Exception {
315         this.server.setHttpService(new RequestBodyStatsService());
316 
317         PostMethod method = new PostMethod("/");
318         method.setRequestHeader("Content-Type", "text/plain");
319         this.client.executeMethod(method);
320         assertEquals(200,method.getStatusLine().getStatusCode());
321         String response = method.getResponseBodyAsString();
322         assertNotNull(method.getRequestHeader("Content-Length"));
323         assertTrue(response.indexOf("No body submitted") >= 0);
324 
325         method = new PostMethod("/");
326         method.setRequestHeader("Content-Type", "text/plain");
327         method.setRequestEntity(new StringRequestEntity("", null, null));
328 		this.client.executeMethod(method);
329         assertEquals(200,method.getStatusLine().getStatusCode());
330         assertNotNull(method.getRequestHeader("Content-Length"));
331         response = method.getResponseBodyAsString();
332         assertTrue(response.indexOf("No body submitted") >= 0);
333 
334         method = new PostMethod("/");
335         method.setRequestHeader("Content-Type", "text/plain");
336         method.setContentChunked(true);
337 		this.client.executeMethod(method);
338         assertEquals(200,method.getStatusLine().getStatusCode());
339         assertNotNull(method.getRequestHeader("Content-Length"));
340         response = method.getResponseBodyAsString();
341         assertTrue(response.indexOf("No body submitted") >= 0);
342 
343         method = new PostMethod("/");
344         method.setRequestHeader("Content-Type", "text/plain");
345         method.setRequestEntity(new StringRequestEntity("", null, null));
346         method.setContentChunked(true);
347 		this.client.executeMethod(method);
348         assertNull(method.getRequestHeader("Content-Length"));
349         assertNotNull(method.getRequestHeader("Transfer-Encoding"));
350         assertEquals(200,method.getStatusLine().getStatusCode());
351         response = method.getResponseBodyAsString();
352         assertTrue(response.indexOf("No body submitted") >= 0);
353     }
354     
355 }
356