All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.robtimus.filesystems.ftp.FTPSEnvironment Maven / Gradle / Ivy

The newest version!
/*
 * FTPSEnvironment.java
 * Copyright 2016 Rob Spoor
 *
 * Licensed 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 com.github.robtimus.filesystems.ftp;

import java.io.IOException;
import java.net.InetAddress;
import java.net.Proxy;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.spi.FileSystemProvider;
import java.security.SecureRandom;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import org.apache.commons.net.ftp.FTPClient.HostnameResolver;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPSClient;
import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory;
import com.github.robtimus.filesystems.FileSystemProviderSupport;

/**
 * A utility class to set up environments that can be used in the {@link FileSystemProvider#newFileSystem(URI, Map)} and
 * {@link FileSystemProvider#newFileSystem(Path, Map)} methods of {@link FTPSFileSystemProvider}.
 *
 * @author Rob Spoor
 */
public class FTPSEnvironment extends FTPEnvironment {

    private static final AtomicReference DEFAULTS = new AtomicReference<>();

    private static final String SECURITY_MODE = "securityMode"; //$NON-NLS-1$
    private static final String SSL_CONTEXT = "sslContext"; //$NON-NLS-1$
    private static final String PROTOCOL = "protocol"; //$NON-NLS-1$
    private static final String AUTH_COMMAND = "authCommand"; //$NON-NLS-1$
    private static final String KEY_MANAGER = "keyManager"; //$NON-NLS-1$
    private static final String TRUST_MANAGER = "trustManager"; //$NON-NLS-1$
    private static final String HOSTNAME_VERIFIER = "hostnameVerifier"; //$NON-NLS-1$
    private static final String ENDPOINT_CHECKING_ENABLED = "endpointCheckingEnabled"; //$NON-NLS-1$
    private static final String ENABLED_SESSION_CREATION = "enabledSessionCreation"; //$NON-NLS-1$
    private static final String NEED_CLIENT_AUTH = "needClientAuth"; //$NON-NLS-1$
    private static final String WANT_CLIENT_AUTH = "wantClientAuth"; //$NON-NLS-1$
    private static final String USE_CLIENT_MODE = "useClientMode"; //$NON-NLS-1$
    private static final String ENABLED_CIPHER_SUITES = "enabledCipherSuites"; //$NON-NLS-1$
    private static final String ENABLED_PROTOCOLS = "enabledProtocols"; //$NON-NLS-1$
    private static final String DATA_CHANNEL_PROTECTION_LEVEL = "dataChannelProtectionLevel"; //$NON-NLS-1$

    /**
     * Creates a new FTPS environment.
     */
    public FTPSEnvironment() {
        super();
    }

    /**
     * Creates a new FTPS environment.
     *
     * @param map The map to wrap.
     */
    public FTPSEnvironment(Map map) {
        super(map);
    }

    @Override
    public FTPSEnvironment withLocalAddress(InetAddress localAddr, int localPort) {
        super.withLocalAddress(localAddr, localPort);
        return this;
    }

    @Override
    public FTPSEnvironment withCredentials(String username, char[] password) {
        super.withCredentials(username, password);
        return this;
    }

    @Override
    public FTPSEnvironment withCredentials(String username, char[] password, String account) {
        super.withCredentials(username, password, account);
        return this;
    }

    @Override
    public FTPSEnvironment withSoTimeout(int timeout) {
        super.withSoTimeout(timeout);
        return this;
    }

    @Override
    public FTPSEnvironment withSendBufferSize(int size) {
        super.withSendBufferSize(size);
        return this;
    }

    @Override
    public FTPSEnvironment withReceiveBufferSize(int size) {
        super.withReceiveBufferSize(size);
        return this;
    }

    @Override
    public FTPSEnvironment withTcpNoDelay(boolean on) {
        super.withTcpNoDelay(on);
        return this;
    }

    @Override
    public FTPSEnvironment withKeepAlive(boolean keepAlive) {
        super.withKeepAlive(keepAlive);
        return this;
    }

    @Override
    public FTPSEnvironment withSoLinger(boolean on, int linger) {
        super.withSoLinger(on, linger);
        return this;
    }

    @Override
    public FTPSEnvironment withSocketFactory(SocketFactory factory) {
        super.withSocketFactory(factory);
        return this;
    }

    @Override
    public FTPSEnvironment withServerSocketFactory(ServerSocketFactory factory) {
        super.withServerSocketFactory(factory);
        return this;
    }

    @Override
    public FTPSEnvironment withConnectTimeout(int timeout) {
        super.withConnectTimeout(timeout);
        return this;
    }

    @Override
    public FTPSEnvironment withProxy(Proxy proxy) {
        super.withProxy(proxy);
        return this;
    }

    @Override
    public FTPSEnvironment withCharset(Charset charset) {
        super.withCharset(charset);
        return this;
    }

    @Override
    public FTPSEnvironment withControlEncoding(String encoding) {
        super.withControlEncoding(encoding);
        return this;
    }

    /**
     * {@inheritDoc}
     *
     * @since 2.1
     */
    @Override
    public FTPSEnvironment withStrictMultilineParsing(boolean strictMultilineParsing) {
        super.withStrictMultilineParsing(strictMultilineParsing);
        return this;
    }

    /**
     * {@inheritDoc}
     *
     * @deprecated Use {@link #withDataTimeout(Duration)} instead.
     */
    @Override
    @Deprecated
    public FTPSEnvironment withDataTimeout(int timeout) {
        super.withDataTimeout(timeout);
        return this;
    }

    /**
     * {@inheritDoc}
     *
     * @since 3.1
     */
    @Override
    public FTPSEnvironment withDataTimeout(Duration timeout) {
        super.withDataTimeout(timeout);
        return this;
    }

    @Override
    public FTPSEnvironment withParserFactory(FTPFileEntryParserFactory parserFactory) {
        super.withParserFactory(parserFactory);
        return this;
    }

    /**
     * {@inheritDoc}
     *
     * @since 3.1
     */
    @Override
    public FTPSEnvironment withIpAddressFromPasvResponse(boolean usingIpAddressFromPasvResponse) {
        super.withIpAddressFromPasvResponse(usingIpAddressFromPasvResponse);
        return this;
    }

    @Override
    public FTPSEnvironment withRemoteVerificationEnabled(boolean enabled) {
        super.withRemoteVerificationEnabled(enabled);
        return this;
    }

    @Override
    public FTPSEnvironment withDefaultDirectory(String pathname) {
        super.withDefaultDirectory(pathname);
        return this;
    }

    @Override
    public FTPSEnvironment withConnectionMode(ConnectionMode connectionMode) {
        super.withConnectionMode(connectionMode);
        return this;
    }

    @Override
    public FTPSEnvironment withActivePortRange(int minPort, int maxPort) {
        super.withActivePortRange(minPort, maxPort);
        return this;
    }

    @Override
    public FTPSEnvironment withActiveExternalIPAddress(String ipAddress) {
        super.withActiveExternalIPAddress(ipAddress);
        return this;
    }

    @Override
    public FTPSEnvironment withPassiveLocalIPAddress(String ipAddress) {
        super.withPassiveLocalIPAddress(ipAddress);
        return this;
    }

    @Override
    public FTPSEnvironment withReportActiveExternalIPAddress(String ipAddress) {
        super.withReportActiveExternalIPAddress(ipAddress);
        return this;
    }

    @Override
    public FTPSEnvironment withBufferSize(int bufferSize) {
        super.withBufferSize(bufferSize);
        return this;
    }

    @Override
    public FTPSEnvironment withSendDataSocketBufferSize(int bufferSizr) {
        super.withSendDataSocketBufferSize(bufferSizr);
        return this;
    }

    @Override
    public FTPSEnvironment withReceiveDataSocketBufferSize(int bufferSize) {
        super.withReceiveDataSocketBufferSize(bufferSize);
        return this;
    }

    @Override
    public FTPSEnvironment withClientConfig(FTPClientConfig clientConfig) {
        super.withClientConfig(clientConfig);
        return this;
    }

    @Override
    public FTPSEnvironment withUseEPSVwithIPv4(boolean selected) {
        super.withUseEPSVwithIPv4(selected);
        return this;
    }

    /**
     * {@inheritDoc}
     *
     * @deprecated Use {@link #withControlKeepAliveTimeout(Duration)} instead.
     */
    @Override
    @Deprecated
    public FTPSEnvironment withControlKeepAliveTimeout(long timeout) {
        super.withControlKeepAliveTimeout(timeout);
        return this;
    }

    /**
     * {@inheritDoc}
     *
     * @since 3.1
     */
    @Override
    public FTPSEnvironment withControlKeepAliveTimeout(Duration timeout) {
        super.withControlKeepAliveTimeout(timeout);
        return this;
    }

    /**
     * {@inheritDoc}
     *
     * @deprecated Use {@link #withControlKeepAliveReplyTimeout(Duration)} instead.
     */
    @Override
    @Deprecated
    public FTPSEnvironment withControlKeepAliveReplyTimeout(int timeout) {
        super.withControlKeepAliveReplyTimeout(timeout);
        return this;
    }

    /**
     * {@inheritDoc}
     *
     * @since 3.1
     */
    @Override
    public FTPSEnvironment withControlKeepAliveReplyTimeout(Duration timeout) {
        super.withControlKeepAliveReplyTimeout(timeout);
        return this;
    }

    /**
     * {@inheritDoc}
     *
     * @since 1.1
     */
    @Override
    public FTPSEnvironment withPassiveNatWorkaroundStrategy(HostnameResolver resolver) {
        super.withPassiveNatWorkaroundStrategy(resolver);
        return this;
    }

    @Override
    public FTPSEnvironment withAutodetectEncoding(boolean autodetect) {
        super.withAutodetectEncoding(autodetect);
        return this;
    }

    /**
     * {@inheritDoc}
     *
     * @since 2.0
     */
    @Override
    public FTPSEnvironment withListHiddenFiles(boolean listHiddenFiles) {
        super.withListHiddenFiles(listHiddenFiles);
        return this;
    }

    /**
     * {@inheritDoc}
     *
     * @since 3.0
     */
    @Override
    public FTPSEnvironment withPoolConfig(FTPPoolConfig poolConfig) {
        super.withPoolConfig(poolConfig);
        return this;
    }

    @Override
    public FTPSEnvironment withFileSystemExceptionFactory(FileSystemExceptionFactory factory) {
        super.withFileSystemExceptionFactory(factory);
        return this;
    }

    @Override
    public FTPSEnvironment withFTPFileStrategyFactory(FTPFileStrategyFactory factory) {
        super.withFTPFileStrategyFactory(factory);
        return this;
    }

    /**
     * Stores the security mode to use.
     * If the security mode is not set, it will default to {@link SecurityMode#EXPLICIT}.
     *
     * @param securityMode The security mode to use.
     * @return This object.
     */
    @QueryParam(SECURITY_MODE)
    public FTPSEnvironment withSecurityMode(SecurityMode securityMode) {
        put(SECURITY_MODE, securityMode);
        return this;
    }

    /**
     * Stores the SSL context to use.
     * If the SSL context is not set, the {@link #withProtocol(String) protocol} will be used instead.
     *
     * @param sslContext The SSL context to use.
     * @return This object.
     */
    public FTPSEnvironment withSSLContext(SSLContext sslContext) {
        put(SSL_CONTEXT, sslContext);
        return this;
    }

    /**
     * Stores the protocol to use.
     * If the protocol is not set, it will default to {@code TLS}.
     * The protocol will be ignored if an {@link #withSSLContext(SSLContext) SSLContext} is stored.
     *
     * @param protocol The protocol to use.
     * @return This object.
     */
    @QueryParam(PROTOCOL)
    public FTPSEnvironment withProtocol(String protocol) {
        put(PROTOCOL, protocol);
        return this;
    }

    /**
     * Stores the AUTH command to use.
     *
     * @param command The AUTH command to use.
     * @return This object.
     */
    @QueryParam(AUTH_COMMAND)
    public FTPSEnvironment withAuthCommand(String command) {
        put(AUTH_COMMAND, command);
        return this;
    }

    /**
     * Stores the key manager to use.
     *
     * @param keyManager The key manager to use.
     * @return This object.
     * @see SSLContext#init(KeyManager[], TrustManager[], SecureRandom)
     */
    public FTPSEnvironment withKeyManager(KeyManager keyManager) {
        put(KEY_MANAGER, keyManager);
        return this;
    }

    /**
     * Stores the trust manager to use.
     *
     * @param trustManager The trust manager to use.
     * @return This object.
     * @see SSLContext#init(KeyManager[], TrustManager[], SecureRandom)
     */
    public FTPSEnvironment withTrustManager(TrustManager trustManager) {
        put(TRUST_MANAGER, trustManager);
        return this;
    }

    /**
     * Stores the hostname verifier to use.
     * The verifier is only used on {@link #withUseClientMode(boolean) client mode} connections.
     *
     * @param hostnameVerifier The hostname verifier to use.
     * @return This object.
     */
    public FTPSEnvironment withHostnameVerifier(HostnameVerifier hostnameVerifier) {
        put(HOSTNAME_VERIFIER, hostnameVerifier);
        return this;
    }

    /**
     * Stores whether or not endpoint identification using the HTTPS algorithm should be enabled.
     * The default behaviour is for this to be disabled.
     * This check is only performed on {@link #withUseClientMode(boolean) client mode} connections.
     *
     * @param enabled {@code true} if endpoint identification should be enabled, or {@code false} if it should be disabled.
     * @return This object.
     * @see SSLSocket#setSSLParameters(SSLParameters)
     * @see SSLParameters#setEndpointIdentificationAlgorithm(String)
     */
    @QueryParam(ENDPOINT_CHECKING_ENABLED)
    public FTPSEnvironment withEndpointCheckingEnabled(boolean enabled) {
        put(ENDPOINT_CHECKING_ENABLED, enabled);
        return this;
    }

    /**
     * Stores whether or not new SSL sessions may be established by sockets.
     *
     * @param established The established socket flag.
     * @return This object.
     * @see SSLSocket#setEnableSessionCreation(boolean)
     */
    @QueryParam(ENABLED_SESSION_CREATION)
    public FTPSEnvironment withEnabledSessionCreation(boolean established) {
        put(ENABLED_SESSION_CREATION, established);
        return this;
    }

    /**
     * Stores whether or not sockets will require client authentication.
     *
     * @param needClientAuth The need client authentication flag.
     * @return This object.
     * @see SSLSocket#setNeedClientAuth(boolean)
     */
    @QueryParam(NEED_CLIENT_AUTH)
    public FTPSEnvironment withNeedClientAuth(boolean needClientAuth) {
        put(NEED_CLIENT_AUTH, needClientAuth);
        return this;
    }

    /**
     * Stores whether or not sockets will request client authentication.
     *
     * @param wantClientAuth The want client authentication flag.
     * @return This object.
     * @see SSLSocket#setWantClientAuth(boolean)
     */
    @QueryParam(WANT_CLIENT_AUTH)
    public FTPSEnvironment withWantClientAuth(boolean wantClientAuth) {
        put(WANT_CLIENT_AUTH, wantClientAuth);
        return this;
    }

    /**
     * Stores whether or not sockets are set to use client mode in their first handshake.
     *
     * @param useClientMode The use client mode flag.
     * @return This object.
     * @see SSLSocket#setUseClientMode(boolean)
     */
    @QueryParam(USE_CLIENT_MODE)
    public FTPSEnvironment withUseClientMode(boolean useClientMode) {
        put(USE_CLIENT_MODE, useClientMode);
        return this;
    }

    /**
     * Stores the names of the cipher suites which could be enabled for use on connections.
     *
     * @param cipherSuites The names of the cipher suites to use.
     * @return This object.
     * @see SSLSocket#setEnabledCipherSuites(String[])
     */
    @QueryParam(ENABLED_CIPHER_SUITES)
    public FTPSEnvironment withEnabledCipherSuites(String... cipherSuites) {
        put(ENABLED_CIPHER_SUITES, cipherSuites);
        return this;
    }

    /**
     * Stores which particular protocol versions are enabled for use on connections.
     *
     * @param protocolVersions The protocol versions to use.
     * @return This object.
     * @see SSLSocket#setEnabledProtocols(String[])
     */
    @QueryParam(ENABLED_PROTOCOLS)
    public FTPSEnvironment withEnabledProtocols(String... protocolVersions) {
        put(ENABLED_PROTOCOLS, protocolVersions);
        return this;
    }

    /**
     * Stores the data channel protection level to use.
     *
     * @param dataChannelProtectionLevel The data channel protection level to use.
     * @return This object.
     * @see SSLSocket#setUseClientMode(boolean)
     * @since 2.2
     */
    @QueryParam(DATA_CHANNEL_PROTECTION_LEVEL)
    public FTPSEnvironment withDataChannelProtectionLevel(DataChannelProtectionLevel dataChannelProtectionLevel) {
        put(DATA_CHANNEL_PROTECTION_LEVEL, dataChannelProtectionLevel);
        return this;
    }

    @Override
    FTPSEnvironment withQueryString(String rawQueryString) throws IOException {
        super.withQueryString(rawQueryString);
        return this;
    }

    @Override
    FTPEnvironment withQueryParam(String name, String value) throws IOException {
        switch (name) {
            case SECURITY_MODE:
                withSecurityMode(SecurityMode.valueOf(value));
                break;
            case PROTOCOL:
                withProtocol(value);
                break;
            case AUTH_COMMAND:
                withAuthCommand(value);
                break;
            case ENDPOINT_CHECKING_ENABLED:
                withEndpointCheckingEnabled(Boolean.parseBoolean(value));
                break;
            case ENABLED_SESSION_CREATION:
                withEnabledSessionCreation(Boolean.parseBoolean(value));
                break;
            case NEED_CLIENT_AUTH:
                withNeedClientAuth(Boolean.parseBoolean(value));
                break;
            case WANT_CLIENT_AUTH:
                withWantClientAuth(Boolean.parseBoolean(value));
                break;
            case USE_CLIENT_MODE:
                withUseClientMode(Boolean.parseBoolean(value));
                break;
            case ENABLED_CIPHER_SUITES:
                withEnabledCipherSuites(value.split(",")); //$NON-NLS-1$
                break;
            case ENABLED_PROTOCOLS:
                withEnabledProtocols(value.split(",")); //$NON-NLS-1$
                break;
            case DATA_CHANNEL_PROTECTION_LEVEL:
                withDataChannelProtectionLevel(DataChannelProtectionLevel.valueOf(value));
                break;
            default:
                super.withQueryParam(name, value);
                break;
        }
        return this;
    }

    @Override
    FTPSClient createClient(String hostname, int port) throws IOException {
        SecurityMode securityMode = FileSystemProviderSupport.getValue(this, SECURITY_MODE, SecurityMode.class, SecurityMode.EXPLICIT);
        boolean isImplicit = securityMode.isImplicit;
        SSLContext context = FileSystemProviderSupport.getValue(this, SSL_CONTEXT, SSLContext.class, null);

        FTPSClient client = createClient(isImplicit, context);
        initializePreConnect(client);
        connect(client, hostname, port);
        initializePostConnect(client);
        login(client);
        initializePostLogin(client);
        verifyConnection(client);
        return client;
    }

    private FTPSClient createClient(boolean isImplicit, SSLContext context) {
        if (context == null) {
            String protocol = FileSystemProviderSupport.getValue(this, PROTOCOL, String.class, null);
            return protocol == null
                    ? new FTPSClient(isImplicit)
                    : new FTPSClient(protocol, isImplicit);
        }
        return new FTPSClient(isImplicit, context);
    }

    void initializePreConnect(FTPSClient client) throws IOException {
        super.initializePreConnect(client);

        configureAuthCommand(client);

        configureKeyManager(client);
        configureTrustManager(client);
        configureHostnameVerifier(client);

        configureEndpointCheckingEnabled(client);

        configureEnabledSessionCreation(client);

        configureNeedClientAuth(client);
        configureWantClientAuth(client);
        configureUseClientMode(client);

        configureEnabledCipherSuites(client);

        configureEnabledProtocols(client);
    }

    private void configureAuthCommand(FTPSClient client) {
        if (containsKey(AUTH_COMMAND)) {
            String auth = FileSystemProviderSupport.getValue(this, AUTH_COMMAND, String.class, null);
            client.setAuthValue(auth);
        }
    }

    private void configureKeyManager(FTPSClient client) {
        if (containsKey(KEY_MANAGER)) {
            KeyManager keyManager = FileSystemProviderSupport.getValue(this, KEY_MANAGER, KeyManager.class, null);
            client.setKeyManager(keyManager);
        }
    }

    private void configureTrustManager(FTPSClient client) {
        if (containsKey(TRUST_MANAGER)) {
            TrustManager trustManager = FileSystemProviderSupport.getValue(this, TRUST_MANAGER, TrustManager.class, null);
            client.setTrustManager(trustManager);
        }
    }

    private void configureHostnameVerifier(FTPSClient client) {
        if (containsKey(HOSTNAME_VERIFIER)) {
            HostnameVerifier hostnameVerifier = FileSystemProviderSupport.getValue(this, HOSTNAME_VERIFIER, HostnameVerifier.class, null);
            client.setHostnameVerifier(hostnameVerifier);
        }
    }

    private void configureEndpointCheckingEnabled(FTPSClient client) {
        if (containsKey(ENDPOINT_CHECKING_ENABLED)) {
            boolean enable = FileSystemProviderSupport.getBooleanValue(this, ENDPOINT_CHECKING_ENABLED);
            client.setEndpointCheckingEnabled(enable);
        }
    }

    private void configureEnabledSessionCreation(FTPSClient client) {
        if (containsKey(ENABLED_SESSION_CREATION)) {
            boolean isCreation = FileSystemProviderSupport.getBooleanValue(this, ENABLED_SESSION_CREATION);
            client.setEnabledSessionCreation(isCreation);
        }
    }

    private void configureNeedClientAuth(FTPSClient client) {
        if (containsKey(NEED_CLIENT_AUTH)) {
            boolean isNeedClientAuth = FileSystemProviderSupport.getBooleanValue(this, NEED_CLIENT_AUTH);
            client.setNeedClientAuth(isNeedClientAuth);
        }
    }

    private void configureWantClientAuth(FTPSClient client) {
        if (containsKey(WANT_CLIENT_AUTH)) {
            boolean isWantClientAuth = FileSystemProviderSupport.getBooleanValue(this, WANT_CLIENT_AUTH);
            client.setWantClientAuth(isWantClientAuth);
        }
    }

    private void configureUseClientMode(FTPSClient client) {
        if (containsKey(USE_CLIENT_MODE)) {
            boolean isClientMode = FileSystemProviderSupport.getBooleanValue(this, USE_CLIENT_MODE);
            client.setUseClientMode(isClientMode);
        }
    }

    private void configureEnabledCipherSuites(FTPSClient client) {
        if (containsKey(ENABLED_CIPHER_SUITES)) {
            String[] cipherSuites = FileSystemProviderSupport.getValue(this, ENABLED_CIPHER_SUITES, String[].class, null);
            client.setEnabledCipherSuites(cipherSuites);
        }
    }

    private void configureEnabledProtocols(FTPSClient client) {
        if (containsKey(ENABLED_PROTOCOLS)) {
            String[] protocolVersions = FileSystemProviderSupport.getValue(this, ENABLED_PROTOCOLS, String[].class, null);
            client.setEnabledProtocols(protocolVersions);
        }
    }

    void initializePostConnect(FTPSClient client) throws IOException {
        super.initializePostConnect(client);

        configureDataChannelProtectionLevel(client);
    }

    private void configureDataChannelProtectionLevel(FTPSClient client) throws IOException {
        if (containsKey(DATA_CHANNEL_PROTECTION_LEVEL)) {
            DataChannelProtectionLevel dataChannelProtectionLevel
                    = FileSystemProviderSupport.getValue(this, DATA_CHANNEL_PROTECTION_LEVEL, DataChannelProtectionLevel.class);
            // 0 means streaming, see https://tools.ietf.org/html/rfc4217#section-9
            client.execPBSZ(0);
            dataChannelProtectionLevel.apply(client);
        }
    }

    /**
     * Copies a map to create a new {@link FTPSEnvironment} instance.
     *
     * @param env The map to copy. It can be an {@link FTPSEnvironment} instance, but does not have to be.
     * @return A new {@link FTPSEnvironment} instance that is a copy of the given map.
     * @since 3.0
     */
    public static FTPSEnvironment copy(Map env) {
        return env == null
                ? new FTPSEnvironment()
                : new FTPSEnvironment(new HashMap<>(env));
    }

    /**
     * Sets the default FTPS environment.
     * This is used in {@link FTPSFileSystemProvider#getPath(URI)} when a file system needs to be created, since no environment can be passed.
     * This way, certain settings like {@link #withPoolConfig(FTPPoolConfig) pool configuration} can still be applied.
     *
     * @param defaultEnvironment The default FTPS environment. Use {@code null} to reset it to an empty environment.
     * @since 3.2
     */
    public static void setDefault(FTPSEnvironment defaultEnvironment) {
        DEFAULTS.set(copy(defaultEnvironment));
    }

    static FTPSEnvironment copyOfDefault() {
        return copy(DEFAULTS.get());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy