/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.harmony.luni.tests.internal.net.www.protocol.http; //import dalvik.annotation.SideEffect; //import dalvik.annotation.BrokenTest; //import dalvik.annotation.KnownFailure; //import dalvik.annotation.TestTargetClass; //import dalvik.annotation.TestTargets; //import dalvik.annotation.TestLevel; //import dalvik.annotation.TestTargetNew; import java.io.IOException; import java.net.Authenticator; import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.PasswordAuthentication; import java.net.Proxy; import java.net.ProxySelector; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketAddress; import java.net.SocketTimeoutException; import java.net.URI; import java.net.URL; import java.util.ArrayList; import junit.framework.TestCase; /** * Tests for <code>HTTPURLConnection</code> class constructors and methods. * */ //@TestTargetClass(HttpURLConnection.class) public class HttpURLConnectionTest extends TestCase { private final static Object bound = new Object(); static class MockServer extends Thread { ServerSocket serverSocket; boolean accepted = false; boolean started = false; public MockServer(String name) throws IOException { super(name); serverSocket = new ServerSocket(0); serverSocket.setSoTimeout(1000); } public int port() { return serverSocket.getLocalPort(); } @Override public void run() { try { synchronized (bound) { started = true; bound.notify(); } try { serverSocket.accept().close(); accepted = true; } catch (SocketTimeoutException ignore) { } serverSocket.close(); } catch (IOException e) { throw new RuntimeException(e); } } } static class MockProxyServer extends MockServer { boolean acceptedAuthorizedRequest; public MockProxyServer(String name) throws Exception { super(name); } @Override public void run() { try { Socket socket = serverSocket.accept(); socket.setSoTimeout(1000); byte[] buff = new byte[1024]; int num = socket.getInputStream().read(buff); socket.getOutputStream().write(( "HTTP/1.0 407 Proxy authentication required\n" + "Proxy-authenticate: Basic realm=\"remotehost\"\n\n") .getBytes()); num = socket.getInputStream().read(buff); if (num == -1) { // this connection was closed, create new one: socket = serverSocket.accept(); socket.setSoTimeout(1000); num = socket.getInputStream().read(buff); } String request = new String(buff, 0, num); acceptedAuthorizedRequest = request.toLowerCase().indexOf("proxy-authorization:") > 0; if (acceptedAuthorizedRequest) { socket.getOutputStream().write(( "HTTP/1.1 200 OK\n\n").getBytes()); } } catch (IOException e) { } } } /** * ProxySelector implementation used in the test. */ static class TestProxySelector extends ProxySelector { // proxy port private int proxy_port; // server port private int server_port; /** * Creates proxy selector instance. * Selector will return the proxy, only if the connection * is made to localhost:server_port. Otherwise it will * return NO_PROXY. * Address of the returned proxy will be localhost:proxy_port. */ public TestProxySelector(int server_port, int proxy_port) { this.server_port = server_port; this.proxy_port = proxy_port; } @Override public java.util.List<Proxy> select(URI uri) { Proxy proxy = Proxy.NO_PROXY; if (("localhost".equals(uri.getHost())) && (server_port == uri.getPort())) { proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", proxy_port)); } ArrayList<Proxy> result = new ArrayList<Proxy>(); result.add(proxy); return result; } @Override public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { // do nothing } } /** * @tests org.apache.harmony.luni.internal.net.www.http.getOutputStream() @TestTargetNew( level = TestLevel.PARTIAL, notes = "Regression test.", method = "getOutputStream", args = {} ) */ public void testGetOutputStream() throws Exception { // Regression for HARMONY-482 MockServer httpServer = new MockServer("ServerSocket for HttpURLConnectionTest"); httpServer.start(); synchronized(bound) { if (!httpServer.started) { bound.wait(5000); } } HttpURLConnection c = (HttpURLConnection) new URL("http://localhost:" + httpServer.port()).openConnection(); c.setDoOutput(true); //use new String("POST") instead of simple "POST" to obtain other //object instances then those that are in HttpURLConnection classes c.setRequestMethod(new String("POST")); c.getOutputStream(); httpServer.join(); } /** * Test checks if the proxy specified in openConnection * method will be used for connection to the server @TestTargetNew( level = TestLevel.PARTIAL, notes = "Verifies if the proxy specified in openConnection method will be used for connection to the server.", method = "usingProxy", args = {} ) */ public void testUsingProxy() throws Exception { // Regression for HARMONY-570 MockServer server = new MockServer("server"); MockServer proxy = new MockServer("proxy"); URL url = new URL("http://localhost:" + server.port()); HttpURLConnection connection = (HttpURLConnection) url .openConnection(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", proxy.port()))); connection.setConnectTimeout(2000); connection.setReadTimeout(2000); server.start(); synchronized(bound) { if (!server.started) bound.wait(5000); } proxy.start(); synchronized(bound) { if (!proxy.started) bound.wait(5000); } connection.connect(); // wait while server and proxy run server.join(); proxy.join(); assertTrue("Connection does not use proxy", connection.usingProxy()); assertTrue("Proxy server was not used", proxy.accepted); HttpURLConnection huc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY); assertFalse(huc.usingProxy()); } /** * Test checks if the proxy provided by proxy selector * will be used for connection to the server @TestTargetNew( level = TestLevel.PARTIAL, notes = "Verifies if the proxy provided by proxy selector will be used for connection to the server.", method = "usingProxy", args = {} ) */ public void testUsingProxySelector() throws Exception { // Regression for HARMONY-570 MockServer server = new MockServer("server"); MockServer proxy = new MockServer("proxy"); URL url = new URL("http://localhost:" + server.port()); // keep default proxy selector ProxySelector defPS = ProxySelector.getDefault(); // replace selector ProxySelector.setDefault( new TestProxySelector(server.port(), proxy.port())); try { HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(2000); connection.setReadTimeout(2000); server.start(); synchronized(bound) { if (!server.started) bound.wait(5000); } proxy.start(); synchronized(bound) { if (!proxy.started) bound.wait(5000); } connection.connect(); // wait while server and proxy run server.join(); proxy.join(); assertTrue("Connection does not use proxy", connection.usingProxy()); assertTrue("Proxy server was not used", proxy.accepted); } finally { // restore default proxy selector ProxySelector.setDefault(defPS); } } /* @TestTargets({ @TestTargetNew( level = TestLevel.PARTIAL, notes = "Regression test.", method = "getResponseCode", args = {} ), @TestTargetNew( level = TestLevel.PARTIAL, notes = "Regression test.", method = "connect", args = {} ) }) @SideEffect("Suffers from side effect of other, currently unknown test") */ public void testProxyAuthorization() throws Exception { // Set up test Authenticator Authenticator.setDefault(new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication( "user", "password".toCharArray()); } }); try { MockProxyServer proxy = new MockProxyServer("ProxyServer"); URL url = new URL("http://remotehost:55555/requested.data"); HttpURLConnection connection = (HttpURLConnection) url.openConnection( new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", proxy.port()))); connection.setConnectTimeout(1000); connection.setReadTimeout(1000); proxy.start(); connection.connect(); assertEquals("unexpected response code", 200, connection.getResponseCode()); proxy.join(); assertTrue("Connection did not send proxy authorization request", proxy.acceptedAuthorizedRequest); } finally { // remove previously set authenticator Authenticator.setDefault(null); } } }