1   /*
2    * $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestProxy.java,v 1.9 2004/11/20 19:35:30 olegk Exp $
3    * $Revision: 1.9 $
4    * $Date: 2004/11/20 19:35:30 $
5    * ====================================================================
6    *
7    *  Copyright 1999-2004 The Apache Software Foundation
8    *
9    *  Licensed under the Apache License, Version 2.0 (the "License");
10   *  you may not use this file except in compliance with the License.
11   *  You may obtain a copy of the License at
12   *
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   *
15   *  Unless required by applicable law or agreed to in writing, software
16   *  distributed under the License is distributed on an "AS IS" BASIS,
17   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   *  See the License for the specific language governing permissions and
19   *  limitations under the License.
20   * ====================================================================
21   *
22   * This software consists of voluntary contributions made by many
23   * individuals on behalf of the Apache Software Foundation.  For more
24   * information on the Apache Software Foundation, please see
25   * <http://www.apache.org/>.
26   *
27   */
28  package org.apache.commons.httpclient;
29  
30  import org.apache.commons.httpclient.auth.AuthScheme;
31  import org.apache.commons.httpclient.auth.AuthScope;
32  import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
33  import org.apache.commons.httpclient.auth.CredentialsProvider;
34  import org.apache.commons.httpclient.methods.GetMethod;
35  import org.apache.commons.httpclient.methods.PostMethod;
36  import org.apache.commons.httpclient.methods.StringRequestEntity;
37  import org.apache.commons.httpclient.protocol.Protocol;
38  import org.apache.commons.httpclient.server.AuthRequestHandler;
39  import org.apache.commons.httpclient.server.HttpRequestHandlerChain;
40  import org.apache.commons.httpclient.server.HttpServiceHandler;
41  import org.apache.commons.httpclient.server.SimpleHttpServer;
42  import org.apache.commons.httpclient.server.SimpleProxy;
43  
44  import junit.framework.Test;
45  import junit.framework.TestCase;
46  import junit.framework.TestSuite;
47  
48  /***
49   * Tests for proxied connections.
50   * 
51   * @author Ortwin Glueck
52   * @author Oleg Kalnichevski
53   */
54  public class TestProxy extends TestCase {
55  
56      private SimpleProxy proxy = null;
57      private SimpleHttpServer httpserver = null;
58      private HttpClient httpclient = null;
59  
60      public TestProxy(String testName) {
61          super(testName);
62      }
63  
64      public static Test suite() {
65          return new TestSuite(TestProxy.class);
66      }
67  
68      protected void setUp() throws Exception {
69          super.setUp();
70          this.proxy = new SimpleProxy();
71          this.httpserver = new SimpleHttpServer();
72          this.httpclient = new HttpClient();
73          this.httpclient.getHostConfiguration().setHost(
74                  this.httpserver.getLocalAddress(), 
75                  this.httpserver.getLocalPort(),
76                  Protocol.getProtocol("http"));
77          this.httpclient.getHostConfiguration().setProxy(
78                  this.proxy.getLocalAddress(), 
79                  this.proxy.getLocalPort());                
80      }
81  
82      protected void tearDown() throws Exception {
83          this.httpclient = null;
84          this.proxy.destroy();
85          this.proxy = null;
86          this.httpserver.destroy();
87          this.httpserver = null;
88          super.tearDown();
89      }
90  
91      class GetItWrongThenGetItRight implements CredentialsProvider {
92          
93          private int hostcount = 0;
94          private int proxycount = 0;
95          
96          public GetItWrongThenGetItRight() {
97              super();
98          }
99          
100         public Credentials getCredentials(AuthScheme scheme, String host, int port, boolean proxy)
101                 throws CredentialsNotAvailableException {
102             if (!proxy) {
103                 this.hostcount++;
104                 return provideCredentials(this.hostcount);
105             } else {
106                 this.proxycount++;
107                 return provideCredentials(this.proxycount);
108             }
109         }
110         
111         private Credentials provideCredentials(int count) {
112             switch (count) {
113             case 1: 
114                 return new UsernamePasswordCredentials("testuser", "wrongstuff");
115             case 2: 
116                 return new UsernamePasswordCredentials("testuser", "testpass");
117             default:
118                 return null;
119             }
120         }
121 
122     }
123     
124     /***
125      * Tests GET via non-authenticating proxy
126      */
127     public void testSimpleGet() throws Exception {
128         this.httpserver.setHttpService(new FeedbackService());
129         GetMethod get = new GetMethod("/");
130         try {
131             this.httpclient.executeMethod(get);
132             assertEquals(HttpStatus.SC_OK, get.getStatusCode());
133         } finally {
134             get.releaseConnection();
135         }
136     }
137     
138     /***
139      * Tests GET via non-authenticating proxy + host auth + connection keep-alive 
140      */
141     public void testGetHostAuthConnKeepAlive() throws Exception {
142 
143         UsernamePasswordCredentials creds = 
144             new UsernamePasswordCredentials("testuser", "testpass");
145         
146         this.httpclient.getState().setCredentials(AuthScope.ANY, creds);
147         
148         HttpRequestHandlerChain handlerchain = new HttpRequestHandlerChain();
149         handlerchain.appendHandler(new AuthRequestHandler(creds, "test", true));
150         handlerchain.appendHandler(new HttpServiceHandler(new FeedbackService()));
151         
152         this.httpserver.setRequestHandler(handlerchain);
153         
154         GetMethod get = new GetMethod("/");
155         try {
156             this.httpclient.executeMethod(get);
157             assertEquals(HttpStatus.SC_OK, get.getStatusCode());
158         } finally {
159             get.releaseConnection();
160         }
161     }
162     
163     /***
164      * Tests GET via non-authenticating proxy + host auth + connection close 
165      */
166     public void testGetHostAuthConnClose() throws Exception {
167 
168         UsernamePasswordCredentials creds = 
169             new UsernamePasswordCredentials("testuser", "testpass");
170         
171         this.httpclient.getState().setCredentials(AuthScope.ANY, creds);
172         
173         HttpRequestHandlerChain handlerchain = new HttpRequestHandlerChain();
174         handlerchain.appendHandler(new AuthRequestHandler(creds, "test", false));
175         handlerchain.appendHandler(new HttpServiceHandler(new FeedbackService()));
176         
177         this.httpserver.setRequestHandler(handlerchain);
178         
179         GetMethod get = new GetMethod("/");
180         try {
181             this.httpclient.executeMethod(get);
182             assertEquals(HttpStatus.SC_OK, get.getStatusCode());
183         } finally {
184             get.releaseConnection();
185         }
186     }
187 
188     /***
189      * Tests GET via non-authenticating proxy + invalid host auth 
190      */
191     public void testGetHostInvalidAuth() throws Exception {
192 
193         UsernamePasswordCredentials creds = 
194             new UsernamePasswordCredentials("testuser", "testpass");
195         
196         this.httpclient.getState().setCredentials(AuthScope.ANY, creds);
197         
198         HttpRequestHandlerChain handlerchain = new HttpRequestHandlerChain();
199         handlerchain.appendHandler(new AuthRequestHandler(creds));
200         handlerchain.appendHandler(new HttpServiceHandler(new FeedbackService()));
201         
202         this.httpclient.getState().setCredentials(AuthScope.ANY,
203                 new UsernamePasswordCredentials("testuser", "wrongstuff"));
204         
205         this.httpserver.setRequestHandler(handlerchain);
206         
207         GetMethod get = new GetMethod("/");
208         try {
209             this.httpclient.executeMethod(get);
210             assertEquals(HttpStatus.SC_UNAUTHORIZED, get.getStatusCode());
211         } finally {
212             get.releaseConnection();
213         }
214     }
215 
216     /***
217      * Tests GET via non-authenticating proxy + intercative host auth + connection keep-alive 
218      */
219     public void testGetInteractiveHostAuthConnKeepAlive() throws Exception {
220 
221         UsernamePasswordCredentials creds = 
222             new UsernamePasswordCredentials("testuser", "testpass");
223         
224         this.httpclient.getParams().setParameter(CredentialsProvider.PROVIDER, 
225                 new GetItWrongThenGetItRight());
226         
227         HttpRequestHandlerChain handlerchain = new HttpRequestHandlerChain();
228         handlerchain.appendHandler(new AuthRequestHandler(creds, "test", true));
229         handlerchain.appendHandler(new HttpServiceHandler(new FeedbackService()));
230         
231         this.httpserver.setRequestHandler(handlerchain);
232         
233         GetMethod get = new GetMethod("/");
234         try {
235             this.httpclient.executeMethod(get);
236             assertEquals(HttpStatus.SC_OK, get.getStatusCode());
237         } finally {
238             get.releaseConnection();
239         }
240     }
241    
242     /***
243      * Tests GET via non-authenticating proxy + intercative host auth + connection close 
244      */
245     public void testGetInteractiveHostAuthConnClose() throws Exception {
246 
247         UsernamePasswordCredentials creds = 
248             new UsernamePasswordCredentials("testuser", "testpass");
249         
250         this.httpclient.getParams().setParameter(CredentialsProvider.PROVIDER, 
251                 new GetItWrongThenGetItRight());
252         
253         HttpRequestHandlerChain handlerchain = new HttpRequestHandlerChain();
254         handlerchain.appendHandler(new AuthRequestHandler(creds, "test", false));
255         handlerchain.appendHandler(new HttpServiceHandler(new FeedbackService()));
256         
257         this.httpserver.setRequestHandler(handlerchain);
258         
259         GetMethod get = new GetMethod("/");
260         try {
261             this.httpclient.executeMethod(get);
262             assertEquals(HttpStatus.SC_OK, get.getStatusCode());
263         } finally {
264             get.releaseConnection();
265         }
266     }
267 
268     /***
269      * Tests POST via non-authenticating proxy
270      */
271     public void testSimplePost() throws Exception {
272         this.httpserver.setHttpService(new FeedbackService());
273         PostMethod post = new PostMethod("/");
274         post.setRequestEntity(new StringRequestEntity("Like tons of stuff"));
275         try {
276             this.httpclient.executeMethod(post);
277             assertEquals(HttpStatus.SC_OK, post.getStatusCode());
278             assertNotNull(post.getResponseBodyAsString());
279         } finally {
280             post.releaseConnection();
281         }
282     }
283 
284     /***
285      * Tests POST via non-authenticating proxy + host auth + connection keep-alive 
286      */
287     public void testPostHostAuthConnKeepAlive() throws Exception {
288         UsernamePasswordCredentials creds = 
289             new UsernamePasswordCredentials("testuser", "testpass");
290         
291         this.httpclient.getState().setCredentials(AuthScope.ANY, creds);
292         
293         HttpRequestHandlerChain handlerchain = new HttpRequestHandlerChain();
294         handlerchain.appendHandler(new AuthRequestHandler(creds, "test", true));
295         handlerchain.appendHandler(new HttpServiceHandler(new FeedbackService()));
296         
297         this.httpserver.setRequestHandler(handlerchain);
298         
299         PostMethod post = new PostMethod("/");
300         post.setRequestEntity(new StringRequestEntity("Like tons of stuff"));
301         try {
302             this.httpclient.executeMethod(post);
303             assertEquals(HttpStatus.SC_OK, post.getStatusCode());
304             assertNotNull(post.getResponseBodyAsString());
305         } finally {
306             post.releaseConnection();
307         }
308     }
309 
310     /***
311      * Tests POST via non-authenticating proxy + host auth + connection close 
312      */
313     public void testPostHostAuthConnClose() throws Exception {
314         UsernamePasswordCredentials creds = 
315             new UsernamePasswordCredentials("testuser", "testpass");
316         
317         this.httpclient.getState().setCredentials(AuthScope.ANY, creds);
318         
319         HttpRequestHandlerChain handlerchain = new HttpRequestHandlerChain();
320         handlerchain.appendHandler(new AuthRequestHandler(creds, "test", false));
321         handlerchain.appendHandler(new HttpServiceHandler(new FeedbackService()));
322         
323         this.httpserver.setRequestHandler(handlerchain);
324         
325         PostMethod post = new PostMethod("/");
326         post.setRequestEntity(new StringRequestEntity("Like tons of stuff"));
327         try {
328             this.httpclient.executeMethod(post);
329             assertEquals(HttpStatus.SC_OK, post.getStatusCode());
330             assertNotNull(post.getResponseBodyAsString());
331         } finally {
332             post.releaseConnection();
333         }
334     }
335 
336     /***
337      * Tests POST via non-authenticating proxy + invalid host auth 
338      */
339     public void testPostHostInvalidAuth() throws Exception {
340 
341         UsernamePasswordCredentials creds = 
342             new UsernamePasswordCredentials("testuser", "testpass");
343         
344         this.httpclient.getState().setCredentials(AuthScope.ANY, creds);
345         
346         HttpRequestHandlerChain handlerchain = new HttpRequestHandlerChain();
347         handlerchain.appendHandler(new AuthRequestHandler(creds));
348         handlerchain.appendHandler(new HttpServiceHandler(new FeedbackService()));
349         
350         this.httpclient.getState().setCredentials(AuthScope.ANY,
351                 new UsernamePasswordCredentials("testuser", "wrongstuff"));
352         
353         this.httpserver.setRequestHandler(handlerchain);
354         
355         PostMethod post = new PostMethod("/");
356         post.setRequestEntity(new StringRequestEntity("Like tons of stuff"));
357         try {
358             this.httpclient.executeMethod(post);
359             assertEquals(HttpStatus.SC_UNAUTHORIZED, post.getStatusCode());
360         } finally {
361             post.releaseConnection();
362         }
363     }
364 
365     /***
366      * Tests POST via non-authenticating proxy + interactive host auth + connection keep-alive 
367      */
368     public void testPostInteractiveHostAuthConnKeepAlive() throws Exception {
369         UsernamePasswordCredentials creds = 
370             new UsernamePasswordCredentials("testuser", "testpass");
371         
372         this.httpclient.getParams().setParameter(CredentialsProvider.PROVIDER, 
373                 new GetItWrongThenGetItRight());
374         
375         HttpRequestHandlerChain handlerchain = new HttpRequestHandlerChain();
376         handlerchain.appendHandler(new AuthRequestHandler(creds, "test", true));
377         handlerchain.appendHandler(new HttpServiceHandler(new FeedbackService()));
378         
379         this.httpserver.setRequestHandler(handlerchain);
380         
381         PostMethod post = new PostMethod("/");
382         post.setRequestEntity(new StringRequestEntity("Like tons of stuff"));
383         try {
384             this.httpclient.executeMethod(post);
385             assertEquals(HttpStatus.SC_OK, post.getStatusCode());
386             assertNotNull(post.getResponseBodyAsString());
387         } finally {
388             post.releaseConnection();
389         }
390     }
391 
392     /***
393      * Tests POST via non-authenticating proxy + interactive host auth + connection close 
394      */
395     public void testPostInteractiveHostAuthConnClose() throws Exception {
396         UsernamePasswordCredentials creds = 
397             new UsernamePasswordCredentials("testuser", "testpass");
398         
399         this.httpclient.getParams().setParameter(CredentialsProvider.PROVIDER, 
400                 new GetItWrongThenGetItRight());
401                 
402         HttpRequestHandlerChain handlerchain = new HttpRequestHandlerChain();
403         handlerchain.appendHandler(new AuthRequestHandler(creds, "test", false));
404         handlerchain.appendHandler(new HttpServiceHandler(new FeedbackService()));
405         
406         this.httpserver.setRequestHandler(handlerchain);
407         
408         PostMethod post = new PostMethod("/");
409         post.setRequestEntity(new StringRequestEntity("Like tons of stuff"));
410         try {
411             this.httpclient.executeMethod(post);
412             assertEquals(HttpStatus.SC_OK, post.getStatusCode());
413             assertNotNull(post.getResponseBodyAsString());
414         } finally {
415             post.releaseConnection();
416         }
417     }
418 }