HttpURLConnectionTest.java revision 229e34b182b98e1dba15d3dc6341954986ae2b7a
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package org.apache.harmony.luni.tests.internal.net.www.protocol.http; 19 20import dalvik.annotation.SideEffect; 21 22import java.io.IOException; 23import java.net.Authenticator; 24import java.net.HttpURLConnection; 25import java.net.InetSocketAddress; 26import java.net.PasswordAuthentication; 27import java.net.Proxy; 28import java.net.ProxySelector; 29import java.net.ServerSocket; 30import java.net.Socket; 31import java.net.SocketAddress; 32import java.net.SocketTimeoutException; 33import java.net.URI; 34import java.net.URL; 35import java.util.ArrayList; 36 37import junit.framework.TestCase; 38 39 40/** 41 * Tests for <code>HTTPURLConnection</code> class constructors and methods. 42 * 43 */ 44public class HttpURLConnectionTest extends TestCase { 45 46 private final static Object bound = new Object(); 47 48 static class MockServer extends Thread { 49 ServerSocket serverSocket; 50 boolean accepted = false; 51 boolean started = false; 52 53 public MockServer(String name) throws IOException { 54 super(name); 55 serverSocket = new ServerSocket(0); 56 serverSocket.setSoTimeout(1000); 57 } 58 59 public int port() { 60 return serverSocket.getLocalPort(); 61 } 62 63 @Override 64 public void run() { 65 try { 66 synchronized (bound) { 67 started = true; 68 bound.notify(); 69 } 70 try { 71 serverSocket.accept().close(); 72 accepted = true; 73 } catch (SocketTimeoutException ignore) { 74 } 75 serverSocket.close(); 76 } catch (IOException e) { 77 throw new RuntimeException(e); 78 } 79 } 80 } 81 82 static class MockProxyServer extends MockServer { 83 84 boolean acceptedAuthorizedRequest; 85 86 public MockProxyServer(String name) throws Exception { 87 super(name); 88 } 89 90 @Override 91 public void run() { 92 try { 93 Socket socket = serverSocket.accept(); 94 socket.setSoTimeout(1000); 95 byte[] buff = new byte[1024]; 96 int num = socket.getInputStream().read(buff); 97 socket.getOutputStream().write(( 98 "HTTP/1.0 407 Proxy authentication required\n" 99 + "Proxy-authenticate: Basic realm=\"remotehost\"\n\n") 100 .getBytes()); 101 num = socket.getInputStream().read(buff); 102 if (num == -1) { 103 // this connection was closed, create new one: 104 socket = serverSocket.accept(); 105 socket.setSoTimeout(1000); 106 num = socket.getInputStream().read(buff); 107 } 108 String request = new String(buff, 0, num); 109 acceptedAuthorizedRequest = 110 request.toLowerCase().indexOf("proxy-authorization:") > 0; 111 if (acceptedAuthorizedRequest) { 112 socket.getOutputStream().write(( 113 "HTTP/1.1 200 OK\n\n").getBytes()); 114 } 115 } catch (IOException e) { 116 } 117 } 118 } 119 120 /** 121 * ProxySelector implementation used in the test. 122 */ 123 static class TestProxySelector extends ProxySelector { 124 // proxy port 125 private int proxy_port; 126 // server port 127 private int server_port; 128 129 /** 130 * Creates proxy selector instance. 131 * Selector will return the proxy, only if the connection 132 * is made to localhost:server_port. Otherwise it will 133 * return NO_PROXY. 134 * Address of the returned proxy will be localhost:proxy_port. 135 */ 136 public TestProxySelector(int server_port, int proxy_port) { 137 this.server_port = server_port; 138 this.proxy_port = proxy_port; 139 } 140 141 @Override 142 public java.util.List<Proxy> select(URI uri) { 143 Proxy proxy = Proxy.NO_PROXY; 144 if (("localhost".equals(uri.getHost())) 145 && (server_port == uri.getPort())) { 146 proxy = new Proxy(Proxy.Type.HTTP, 147 new InetSocketAddress("localhost", proxy_port)); 148 } 149 ArrayList<Proxy> result = new ArrayList<Proxy>(); 150 result.add(proxy); 151 return result; 152 } 153 154 @Override 155 public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { 156 // do nothing 157 } 158 } 159 160 /** 161 * org.apache.harmony.luni.internal.net.www.http.getOutputStream() 162 */ 163 public void testGetOutputStream() throws Exception { 164 // Regression for HARMONY-482 165 MockServer httpServer = 166 new MockServer("ServerSocket for HttpURLConnectionTest"); 167 httpServer.start(); 168 synchronized(bound) { 169 if (!httpServer.started) { 170 bound.wait(5000); 171 } 172 } 173 HttpURLConnection c = (HttpURLConnection) 174 new URL("http://localhost:" + httpServer.port()).openConnection(); 175 c.setDoOutput(true); 176 //use new String("POST") instead of simple "POST" to obtain other 177 //object instances then those that are in HttpURLConnection classes 178 c.setRequestMethod(new String("POST")); 179 c.getOutputStream(); 180 httpServer.join(); 181 } 182 183 184 /** 185 * Test checks if the proxy specified in openConnection 186 * method will be used for connection to the server 187 */ 188 public void testUsingProxy() throws Exception { 189 // Regression for HARMONY-570 190 MockServer server = new MockServer("server"); 191 MockServer proxy = new MockServer("proxy"); 192 193 URL url = new URL("http://localhost:" + server.port()); 194 195 HttpURLConnection connection = (HttpURLConnection) url 196 .openConnection(new Proxy(Proxy.Type.HTTP, 197 new InetSocketAddress("localhost", 198 proxy.port()))); 199 connection.setConnectTimeout(2000); 200 connection.setReadTimeout(2000); 201 202 server.start(); 203 synchronized(bound) { 204 if (!server.started) bound.wait(5000); 205 } 206 proxy.start(); 207 synchronized(bound) { 208 if (!proxy.started) bound.wait(5000); 209 } 210 211 connection.connect(); 212 213 // wait while server and proxy run 214 server.join(); 215 proxy.join(); 216 217 assertTrue("Connection does not use proxy", connection.usingProxy()); 218 assertTrue("Proxy server was not used", proxy.accepted); 219 220 HttpURLConnection huc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY); 221 assertFalse(huc.usingProxy()); 222 } 223 224 /** 225 * Test checks if the proxy provided by proxy selector 226 * will be used for connection to the server 227 */ 228 public void testUsingProxySelector() throws Exception { 229 // Regression for HARMONY-570 230 MockServer server = new MockServer("server"); 231 MockServer proxy = new MockServer("proxy"); 232 233 URL url = new URL("http://localhost:" + server.port()); 234 235 // keep default proxy selector 236 ProxySelector defPS = ProxySelector.getDefault(); 237 // replace selector 238 ProxySelector.setDefault( 239 new TestProxySelector(server.port(), proxy.port())); 240 241 try { 242 HttpURLConnection connection = 243 (HttpURLConnection) url.openConnection(); 244 connection.setConnectTimeout(2000); 245 connection.setReadTimeout(2000); 246 247 server.start(); 248 synchronized(bound) { 249 if (!server.started) bound.wait(5000); 250 } 251 proxy.start(); 252 synchronized(bound) { 253 if (!proxy.started) bound.wait(5000); 254 } 255 connection.connect(); 256 257 // wait while server and proxy run 258 server.join(); 259 proxy.join(); 260 261 assertTrue("Connection does not use proxy", 262 connection.usingProxy()); 263 assertTrue("Proxy server was not used", proxy.accepted); 264 } finally { 265 // restore default proxy selector 266 ProxySelector.setDefault(defPS); 267 } 268 } 269 @SideEffect("Suffers from side effect of other, currently unknown test") 270 public void testProxyAuthorization() throws Exception { 271 // Set up test Authenticator 272 Authenticator.setDefault(new Authenticator() { 273 @Override 274 protected PasswordAuthentication getPasswordAuthentication() { 275 return new PasswordAuthentication( 276 "user", "password".toCharArray()); 277 } 278 }); 279 280 try { 281 MockProxyServer proxy = new MockProxyServer("ProxyServer"); 282 283 URL url = new URL("http://remotehost:55555/requested.data"); 284 HttpURLConnection connection = 285 (HttpURLConnection) url.openConnection( 286 new Proxy(Proxy.Type.HTTP, 287 new InetSocketAddress("localhost", proxy.port()))); 288 connection.setConnectTimeout(1000); 289 connection.setReadTimeout(1000); 290 291 proxy.start(); 292 293 connection.connect(); 294 assertEquals("unexpected response code", 295 200, connection.getResponseCode()); 296 proxy.join(); 297 assertTrue("Connection did not send proxy authorization request", 298 proxy.acceptedAuthorizedRequest); 299 } finally { 300 // remove previously set authenticator 301 Authenticator.setDefault(null); 302 } 303 } 304 305} 306