1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.vfs2;
18
19 import java.net.Inet6Address;
20 import java.net.InetAddress;
21 import java.net.NetworkInterface;
22 import java.net.SocketException;
23 import java.time.Duration;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.Enumeration;
27 import java.util.List;
28
29 import org.apache.commons.lang3.StringUtils;
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.junit.Test;
33
34 public class IPv6LocalConnectionTests extends AbstractProviderTestCase {
35
36 private static final String LOOPBACK = "0:0:0:0:0:0:0:1";
37 private static final Log log = LogFactory.getLog(IPv6LocalConnectionTests.class);
38
39 private static List<String> getLocalIPv6Addresses() throws SocketException {
40 final Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
41 final List<String> result = new ArrayList<>();
42 for (final NetworkInterface networkInterface : Collections.list(networkInterfaces)) {
43 if (!networkInterface.isUp() || networkInterface.isLoopback()
44
45 || networkInterface.getName().startsWith("utun")) {
46 continue;
47 }
48 for (final InetAddress inetAddress : Collections.list(networkInterface.getInetAddresses())) {
49 if (inetAddress instanceof Inet6Address && !inetAddress.isLoopbackAddress() && !inetAddress.isMulticastAddress()) {
50 result.add(StringUtils.substringBefore(inetAddress.getHostAddress(), "%"));
51 }
52 }
53 }
54
55 if (!result.contains(LOOPBACK)) {
56 result.add(LOOPBACK);
57 }
58 return result;
59 }
60
61 @Override
62 protected Capability[] getRequiredCapabilities() {
63 return new Capability[] { Capability.URI, Capability.READ_CONTENT };
64 }
65
66 @Override
67 protected void runTest() throws Throwable {
68 final List<String> localIPv6Addresses = getLocalIPv6Addresses();
69 if (localIPv6Addresses.isEmpty()) {
70 log.info("Local machine must have IPv6 address to run this test");
71 return;
72 }
73 super.runTest();
74 }
75
76 private FileSystemOptions setupConnectionTimeoutHints(final FileSystem fileSystem) {
77
78
79
80 final FileSystemOptions result = (FileSystemOptions) fileSystem.getFileSystemOptions().clone();
81
82 final Duration timeout = Duration.ofSeconds(5);
83
84 result.setOption(fileSystem.getClass(), "org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder.CONNECT_TIMEOUT", timeout);
85 result.setOption(fileSystem.getClass(), "org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder.TIMEOUT", timeout);
86
87 result.setOption(fileSystem.getClass(), "http.connection.timeout", timeout);
88 result.setOption(fileSystem.getClass(), "http.socket.timeout", timeout);
89
90
91
92 result.setOption(fileSystem.getClass(), "org.apache.commons.vfs2.provider.ftp.FtpFileSystemConfigBuilder.CONNECT_TIMEOUT", timeout);
93 result.setOption(fileSystem.getClass(), "org.apache.commons.vfs2.provider.ftp.FtpFileSystemConfigBuilder.SO_TIMEOUT", timeout);
94
95 return result;
96 }
97
98 @Test
99 public void testConnectIPv6UrlLocal() throws Exception {
100 final List<String> localIPv6Addresses = getLocalIPv6Addresses();
101 boolean connected = false;
102 for (final String ipv6Address : localIPv6Addresses) {
103 final String ipv6Url = StringUtils.replace(getReadFolder().getURL().toString(), "localhost", "[" + ipv6Address + "]");
104 try {
105 final FileSystem fileSystem = getFileSystem();
106
107 final FileObject readFolderObject = getManager().resolveFile(ipv6Url, setupConnectionTimeoutHints(fileSystem));
108 connected = connected || readFolderObject.resolveFile("file1.txt").getContent().getByteArray() != null;
109 } catch (final FileSystemException e) {
110
111
112 log.warn("Failed to connect to some of the local IPv6 network addresses", e);
113 }
114 }
115 assertTrue("None of the discovered local IPv6 network addresses has responded for connection: " + localIPv6Addresses, connected);
116 }
117
118 }