blob: d7a693cd4b7c35ba3a1848d044830a2b25f5089a [file] [log] [blame]
/*
* 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);
}
}
}