1   /*
2    * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/oac.hc3x/trunk/src/test/org/apache/commons/httpclient/TestVirtualHost.java $
3    * $Revision: 1425331 $
4    * $Date: 2012-12-22 19:29:41 +0100 (Sat, 22 Dec 2012) $
5    * ====================================================================
6    *
7    *  Licensed to the Apache Software Foundation (ASF) under one or more
8    *  contributor license agreements.  See the NOTICE file distributed with
9    *  this work for additional information regarding copyright ownership.
10   *  The ASF licenses this file to You under the Apache License, Version 2.0
11   *  (the "License"); you may not use this file except in compliance with
12   *  the License.  You may obtain a copy of the License at
13   *
14   *      http://www.apache.org/licenses/LICENSE-2.0
15   *
16   *  Unless required by applicable law or agreed to in writing, software
17   *  distributed under the License is distributed on an "AS IS" BASIS,
18   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19   *  See the License for the specific language governing permissions and
20   *  limitations under the License.
21   * ====================================================================
22   *
23   * This software consists of voluntary contributions made by many
24   * individuals on behalf of the Apache Software Foundation.  For more
25   * information on the Apache Software Foundation, please see
26   * <http://www.apache.org/>.
27   *
28   * [Additional notices, if required by prior licensing conditions]
29   *
30   */
31  
32  package org.apache.commons.httpclient;
33  
34  import java.io.IOException;
35  import java.net.InetAddress;
36  import java.net.Socket;
37  import java.net.UnknownHostException;
38  
39  import junit.framework.Test;
40  import junit.framework.TestSuite;
41  
42  import org.apache.commons.httpclient.methods.GetMethod;
43  import org.apache.commons.httpclient.params.HttpConnectionParams;
44  import org.apache.commons.httpclient.protocol.Protocol;
45  import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
46  import org.apache.commons.httpclient.server.HttpService;
47  import org.apache.commons.httpclient.server.RequestLine;
48  import org.apache.commons.httpclient.server.SimpleRequest;
49  import org.apache.commons.httpclient.server.SimpleResponse;
50  
51  /***
52   * HTTP protocol versioning tests.
53   *
54   * @author Oleg Kalnichevski
55   * 
56   * @version $Revision: 1425331 $
57   */
58  public class TestVirtualHost extends HttpClientTestBase {
59  
60      // ------------------------------------------------------------ Constructor
61      public TestVirtualHost(final String testName) throws IOException {
62          super(testName);
63      }
64  
65      // ------------------------------------------------------------------- Main
66      public static void main(String args[]) {
67          String[] testCaseName = { TestVirtualHost.class.getName() };
68          junit.textui.TestRunner.main(testCaseName);
69      }
70  
71      // ------------------------------------------------------- TestCase Methods
72  
73      public static Test suite() {
74          return new TestSuite(TestVirtualHost.class);
75      }
76  
77      private class VirtualService implements HttpService {
78  
79          public VirtualService() {
80              super();
81          }
82  
83          public boolean process(final SimpleRequest request, final SimpleResponse response)
84              throws IOException
85          {
86              HttpVersion httpversion = request.getRequestLine().getHttpVersion();
87              Header hostheader = request.getFirstHeader("Host");
88              if (hostheader == null) {
89                  response.setStatusLine(httpversion, HttpStatus.SC_BAD_REQUEST);
90                  response.setBodyString("Host header missing");
91              } else {
92                  response.setStatusLine(httpversion, HttpStatus.SC_OK);
93                  response.setBodyString(hostheader.getValue());
94              }
95              return true;
96          }
97      }
98  
99      public void testVirtualHostHeader() throws IOException {
100         this.server.setHttpService(new VirtualService());
101 
102         GetMethod httpget = new GetMethod("/test/");
103         
104         HostConfiguration hostconf = new HostConfiguration();
105         hostconf.setHost(this.server.getLocalAddress(), this.server.getLocalPort(), "http");
106         hostconf.getParams().setVirtualHost("somehost");
107         try {
108             this.client.executeMethod(hostconf, httpget);
109             String hostheader = "somehost:" + this.server.getLocalPort();
110             assertEquals(hostheader, httpget.getResponseBodyAsString());
111         } finally {
112             httpget.releaseConnection();
113         }
114     }
115 
116     public void testNoVirtualHostHeader() throws IOException {
117         this.server.setHttpService(new VirtualService());
118 
119         GetMethod httpget = new GetMethod("/test/");
120         
121         HostConfiguration hostconf = new HostConfiguration();
122         hostconf.setHost(this.server.getLocalAddress(), this.server.getLocalPort(), "http");
123         hostconf.getParams().setVirtualHost(null);
124         try {
125             this.client.executeMethod(hostconf, httpget);
126             String hostheader = this.server.getLocalAddress() + ":" + this.server.getLocalPort();
127             assertEquals(hostheader, httpget.getResponseBodyAsString());
128         } finally {
129             httpget.releaseConnection();
130         }
131     }
132     
133     private class VirtualHostService implements HttpService {
134 
135         public VirtualHostService() {
136             super();
137         }
138 
139         public boolean process(final SimpleRequest request, final SimpleResponse response)
140             throws IOException {
141             RequestLine reqline = request.getRequestLine();
142             HttpVersion ver = reqline.getHttpVersion();
143             Header header =  request.getFirstHeader("Host");
144             if (header == null) {
145                 response.setStatusLine(ver, HttpStatus.SC_BAD_REQUEST);
146                 return true;
147             }
148             String host = header.getValue();
149             if (host.equalsIgnoreCase("whatever.com")) {
150                 response.setStatusLine(ver, HttpStatus.SC_MOVED_TEMPORARILY);
151                 response.setHeader(new Header("Location", "testhttp://www.whatever.com/"));
152                 return true;
153             } else if (host.equalsIgnoreCase("www.whatever.com")) {
154                 response.setStatusLine(ver, HttpStatus.SC_MOVED_TEMPORARILY);
155                 response.setHeader(new Header("Location", "testhttp://www.whatever.co.nz/"));
156                 return true;
157             } else if (host.equalsIgnoreCase("www.whatever.co.nz")) {
158                 response.setStatusLine(ver, HttpStatus.SC_OK);
159                 return true;
160             } else {
161                 response.setStatusLine(ver, HttpStatus.SC_NOT_FOUND);
162                 return true;
163             }
164         }
165     }
166     
167     private class VirtualSocketFactory implements ProtocolSocketFactory {
168         
169         private final String hostname;
170         private final int port;
171         
172         public VirtualSocketFactory(final String hostname, int port) {
173             super();
174             this.hostname = hostname;
175             this.port = port;
176         }
177 
178         public Socket createSocket(
179                 final String host, 
180                 int port, 
181                 final InetAddress localAddress, 
182                 int localPort, 
183                 final HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
184             return new Socket(this.hostname, this.port);
185         }
186 
187         public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException, UnknownHostException {
188             return new Socket(this.hostname, this.port);
189         }
190 
191         public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
192             return new Socket(this.hostname, this.port);
193         }
194         
195     }
196 
197     public void testRedirectWithVirtualHost() throws IOException {
198         String host = this.server.getLocalAddress();
199         int port = this.server.getLocalPort();
200 
201         Protocol testhttp = new Protocol("http", new VirtualSocketFactory(host, port), port);
202         Protocol.registerProtocol("testhttp", testhttp);
203         try {
204             this.server.setHttpService(new VirtualHostService());
205             this.client.getHostConfiguration().setHost(host, port, "testhttp");
206             this.client.getHostConfiguration().getParams().setVirtualHost("whatever.com");
207             GetMethod httpget = new GetMethod("/");
208             httpget.setFollowRedirects(true);
209             try {
210                 this.client.executeMethod(httpget);
211                 assertEquals(HttpStatus.SC_OK, httpget.getStatusCode());
212                 assertEquals("http://www.whatever.co.nz/", httpget.getURI().toString());
213             } finally {
214                 httpget.releaseConnection();
215             }
216         } finally {
217             Protocol.unregisterProtocol("testhttp");
218         }
219         
220     }
221     
222 }