blob: 113655d14f75534150c1b38c704d078abd78b7d5 [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
*
* https://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.ivy.util.url;
import org.apache.ivy.TestHelper;
import org.apache.ivy.core.settings.NamedTimeoutConstraint;
import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.url.URLHandler.URLInfo;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Random;
import static org.apache.ivy.plugins.resolver.IBiblioResolver.DEFAULT_M2_ROOT;
import static org.hamcrest.Matchers.endsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* Test {@link HttpClientHandler}
*/
public class HttpclientURLHandlerTest {
// remote.test
private File testDir;
private HttpClientHandler handler;
private final TimeoutConstraint defaultTimeoutConstraint;
{
defaultTimeoutConstraint = new NamedTimeoutConstraint("default-http-client-handler-timeout");
((NamedTimeoutConstraint) defaultTimeoutConstraint).setConnectionTimeout(5000);
}
@Rule
public ExpectedException expExc = ExpectedException.none();
@Before
public void setUp() {
testDir = new File("build/HttpclientURLHandlerTest");
testDir.mkdirs();
handler = new HttpClientHandler();
}
@After
public void tearDown() {
try {
handler.close();
} catch (Exception e) {
// ignore
}
FileUtil.forceDelete(testDir);
}
@Test
public void testIsReachable() throws Exception {
assertTrue("URL resource was expected to be reachable",
handler.isReachable(new URL("http://www.google.fr/"), defaultTimeoutConstraint));
assertFalse("URL resource was expected to be unreachable",
handler.isReachable(new URL("http://www.google.fr/unknownpage.html"), defaultTimeoutConstraint));
}
/**
* Test case for IVY-390.
*
* @throws Exception if something goes wrong
* @see <a href="https://issues.apache.org/jira/browse/IVY-390">IVY-390</a>
*/
@SuppressWarnings({"resource", "deprecation"})
@Test
public void testGetURLInfo() throws Exception {
final TimeoutConstrainedURLHandler handler = new HttpClientHandler();
assertTrue("Default Maven URL must end with '/'", DEFAULT_M2_ROOT.endsWith("/"));
URLInfo info = handler.getURLInfo(new URL(DEFAULT_M2_ROOT
+ "commons-lang/commons-lang/[1.0,3.0[/commons-lang-[1.0,3.0[.pom"), defaultTimeoutConstraint);
assertEquals(TimeoutConstrainedURLHandler.UNAVAILABLE, info);
}
@Test
public void testContentEncoding() throws Exception {
assertDownloadOK(new URL("http://carsten.codimi.de/gzip.yaws/daniels.html"), new File(
testDir, "gzip.txt"));
assertDownloadOK(new URL(
"http://carsten.codimi.de/gzip.yaws/daniels.html?deflate=on&zlib=on"), new File(
testDir, "deflate-zlib.txt"));
assertDownloadOK(new URL("http://carsten.codimi.de/gzip.yaws/daniels.html?deflate=on"),
new File(testDir, "deflate.txt"));
assertDownloadOK(new URL("http://carsten.codimi.de/gzip.yaws/a5.ps"), new File(testDir,
"a5-gzip.ps"));
assertDownloadOK(new URL("http://carsten.codimi.de/gzip.yaws/a5.ps?deflate=on"), new File(
testDir, "a5-deflate.ps"));
assertDownloadOK(new URL("http://carsten.codimi.de/gzip.yaws/nh80.pdf"), new File(testDir,
"nh80-gzip.pdf"));
assertDownloadOK(new URL("http://carsten.codimi.de/gzip.yaws/nh80.pdf?deflate=on"),
new File(testDir, "nh80-deflate.pdf"));
}
/**
* Tests that the {@link HttpClientHandler}, backed by
* {@link CredentialsStore Ivy credentials store} works as expected when it interacts
* with a HTTP server which requires authentication for accessing resources.
*
* @throws Exception if something goes wrong
* @see <a href="https://issues.apache.org/jira/browse/IVY-1336">IVY-1336</a>
*/
@Test
public void testCredentials() throws Exception {
// we catch it and check for presence of 401 in the exception message.
// It's not exactly an contract that the IOException will have the 401 message
// but for now that's how it's implemented and it's fine to check for the presence
// of that message at the moment
expExc.expect(IOException.class);
expExc.expectMessage(endsWith("ivysettings.xml' 401 - 'Unauthorized"));
final CredentialsStore credentialsStore = CredentialsStore.INSTANCE;
final String realm = "test-http-client-handler-realm";
final String host = "localhost";
final Random random = new Random();
final String userName = "test-http-user-" + random.nextInt();
final String password = "pass-" + random.nextInt();
credentialsStore.addCredentials(realm, host, userName, password);
final InetSocketAddress serverBindAddr = new InetSocketAddress("localhost", TestHelper.getMaybeAvailablePort());
final String contextRoot = "/testHttpClientHandler";
final Path repoRoot = new File("test/repositories").toPath();
assertTrue(repoRoot + " is not a directory", Files.isDirectory(repoRoot));
// create a server backed by BASIC auth with the set of "allowed" credentials
try (final AutoCloseable server = TestHelper.createBasicAuthHttpServerBackedRepo(serverBindAddr,
contextRoot, repoRoot, realm, Collections.singletonMap(userName, password))) {
final File target = new File(testDir, "downloaded.xml");
assertFalse("File " + target + " already exists", target.exists());
final URL src = new URL("http://localhost:" + serverBindAddr.getPort() + "/"
+ contextRoot + "/ivysettings.xml");
// download it
handler.download(src, target, null, defaultTimeoutConstraint);
assertTrue("File " + target + " was not downloaded from " + src, target.isFile());
}
// now create a server backed by BASIC auth with a set of credentials that do *not* match
// with what the Ivy credentials store will return for a given realm+host combination, i.e.
// Ivy credential store will return back invalid credentials and the server will reject them
try (final AutoCloseable server = TestHelper.createBasicAuthHttpServerBackedRepo(serverBindAddr,
contextRoot, repoRoot, realm, Collections.singletonMap("other-" + userName, "other-" + password))) {
final File target = new File(testDir, "should-not-have-been-downloaded.xml");
assertFalse("File " + target + " already exists", target.exists());
final URL src = new URL("http://localhost:" + serverBindAddr.getPort() + "/"
+ contextRoot + "/ivysettings.xml");
// download it (expected to fail)
handler.download(src, target, null, defaultTimeoutConstraint);
}
}
private void assertDownloadOK(final URL url, final File file) throws Exception {
handler.download(url, file, null, defaultTimeoutConstraint);
assertTrue("Content from " + url + " wasn't downloaded to " + file, file.exists());
assertTrue("Unexpected content at " + file + " for resource that was downloaded from "
+ url, file.isFile() && file.length() > 0);
}
}