Example usage for org.apache.http.client.config AuthSchemes BASIC

List of usage examples for org.apache.http.client.config AuthSchemes BASIC

Introduction

In this page you can find the example usage for org.apache.http.client.config AuthSchemes BASIC.

Prototype

String BASIC

To view the source code for org.apache.http.client.config AuthSchemes BASIC.

Click Source Link

Document

Basic authentication scheme as defined in RFC2617 (considered inherently insecure, but most widely supported)

Usage

From source file:com.jfrog.bintray.client.impl.HttpClientConfigurator.java

private void configureProxy(ProxyConfig proxy) {
    if (proxy != null) {
        config.setProxy(new HttpHost(proxy.getHost(), proxy.getPort()));
        if (proxy.getUserName() != null) {
            Credentials creds = null;/*w w w.j  a v a  2s. co  m*/
            if (proxy.getNtDomain() == null) {
                creds = new UsernamePasswordCredentials(proxy.getUserName(), proxy.getPassword());
                List<String> authPrefs = Arrays.asList(AuthSchemes.DIGEST, AuthSchemes.BASIC, AuthSchemes.NTLM);
                config.setProxyPreferredAuthSchemes(authPrefs);

                // preemptive proxy authentication
                builder.addInterceptorFirst(new ProxyPreemptiveAuthInterceptor());
            } else {
                try {
                    String ntHost = StringUtils.isBlank(proxy.getNtHost())
                            ? InetAddress.getLocalHost().getHostName()
                            : proxy.getNtHost();
                    creds = new NTCredentials(proxy.getUserName(), proxy.getPassword(), ntHost,
                            proxy.getNtDomain());
                } catch (UnknownHostException e) {
                    log.error("Failed to determine required local hostname for NTLM credentials.", e);
                }
            }
            if (creds != null) {
                credsProvider.setCredentials(
                        new AuthScope(proxy.getHost(), proxy.getPort(), AuthScope.ANY_REALM), creds);
                if (proxy.getRedirectToHosts() != null) {
                    for (String hostName : proxy.getRedirectToHosts()) {
                        credsProvider.setCredentials(
                                new AuthScope(hostName, AuthScope.ANY_PORT, AuthScope.ANY_REALM), creds);
                    }
                }
            }
        }
    }
}

From source file:org.apache.calcite.avatica.remote.AvaticaCommonsHttpClientImpl.java

@Override
public void setUsernamePassword(AuthenticationType authType, String username, String password) {
    this.credentials = new UsernamePasswordCredentials(Objects.requireNonNull(username),
            Objects.requireNonNull(password));

    this.credentialsProvider = new BasicCredentialsProvider();
    credentialsProvider.setCredentials(AuthScope.ANY, credentials);

    RegistryBuilder<AuthSchemeProvider> authRegistryBuilder = RegistryBuilder.create();
    switch (authType) {
    case BASIC://from w  w w .j  a  va2s .  co m
        authRegistryBuilder.register(AuthSchemes.BASIC, new BasicSchemeFactory());
        break;
    case DIGEST:
        authRegistryBuilder.register(AuthSchemes.DIGEST, new DigestSchemeFactory());
        break;
    default:
        throw new IllegalArgumentException("Unsupported authentiation type: " + authType);
    }
    this.authRegistry = authRegistryBuilder.build();
}

From source file:org.sonatype.nexus.apachehttpclient.Hc4ProviderBase.java

protected void applyAuthenticationConfig(final Builder builder, final RemoteAuthenticationSettings ras,
        final HttpHost proxyHost) {
    if (ras != null) {
        String authScope = "target";
        if (proxyHost != null) {
            authScope = proxyHost.toHostString() + " proxy";
        }//from  www.  ja va  2  s  . c om

        final List<String> authorisationPreference = Lists.newArrayListWithExpectedSize(3);
        authorisationPreference.add(AuthSchemes.DIGEST);
        authorisationPreference.add(AuthSchemes.BASIC);
        Credentials credentials = null;
        if (ras instanceof ClientSSLRemoteAuthenticationSettings) {
            throw new IllegalArgumentException("SSL client authentication not yet supported!");
        } else if (ras instanceof NtlmRemoteAuthenticationSettings) {
            final NtlmRemoteAuthenticationSettings nras = (NtlmRemoteAuthenticationSettings) ras;
            // Using NTLM auth, adding it as first in policies
            authorisationPreference.add(0, AuthSchemes.NTLM);
            log.debug("{} authentication setup for NTLM domain '{}'", authScope, nras.getNtlmDomain());
            credentials = new NTCredentials(nras.getUsername(), nras.getPassword(), nras.getNtlmHost(),
                    nras.getNtlmDomain());
        } else if (ras instanceof UsernamePasswordRemoteAuthenticationSettings) {
            final UsernamePasswordRemoteAuthenticationSettings uras = (UsernamePasswordRemoteAuthenticationSettings) ras;
            log.debug("{} authentication setup for remote storage with username '{}'", authScope,
                    uras.getUsername());
            credentials = new UsernamePasswordCredentials(uras.getUsername(), uras.getPassword());
        }

        if (credentials != null) {
            if (proxyHost != null) {
                builder.setCredentials(new AuthScope(proxyHost), credentials);
                builder.getRequestConfigBuilder().setProxyPreferredAuthSchemes(authorisationPreference);
            } else {
                builder.setCredentials(AuthScope.ANY, credentials);
                builder.getRequestConfigBuilder().setTargetPreferredAuthSchemes(authorisationPreference);
            }
        }
    }
}

From source file:io.mandrel.requests.http.ApacheHttpRequester.java

public void init() {

    available = new Semaphore(maxParallel(), true);

    SSLContext sslContext = SSLContexts.createSystemDefault();
    HostnameVerifier hostnameVerifier = new DefaultHostnameVerifier();

    Registry<ConnectionSocketFactory> sessionStrategyRegistry = RegistryBuilder
            .<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.getSocketFactory())
            .register("https", new SSLConnectionSocketFactory(sslContext, hostnameVerifier)).build();

    DnsResolver dnsResolver = new SystemDefaultDnsResolver() {
        @Override/*w ww  . jav  a 2  s  .  co m*/
        public InetAddress[] resolve(final String host) throws UnknownHostException {
            if (host.equalsIgnoreCase("localhost")) {
                return new InetAddress[] { InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }) };
            } else {
                return new InetAddress[] { nameResolver().resolve(host) };
            }
        }
    };

    // Create a connection manager with custom configuration.
    PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(
            sessionStrategyRegistry, dnsResolver);

    // Create message constraints
    MessageConstraints messageConstraints = MessageConstraints.custom().setMaxHeaderCount(maxHeaderCount)
            .setMaxLineLength(maxLineLength).build();

    // Create connection configuration
    ConnectionConfig connectionConfig = ConnectionConfig.custom()
            .setMalformedInputAction(CodingErrorAction.IGNORE)
            .setUnmappableInputAction(CodingErrorAction.IGNORE).setCharset(Consts.UTF_8)
            .setMessageConstraints(messageConstraints).build();
    connManager.setDefaultConnectionConfig(connectionConfig);

    // Configure total max or per route limits for persistent connections
    // that can be kept in the pool or leased by the connection manager.
    connManager.setMaxTotal(maxPersistentConnections());
    connManager.setDefaultMaxPerRoute(maxPersistentConnections());

    // TODO
    // Use custom credentials provider if necessary.
    // CredentialsProvider credentialsProvider = new
    // BasicCredentialsProvider();

    // Create global request configuration
    defaultRequestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.DEFAULT)
            .setExpectContinueEnabled(true).setStaleConnectionCheckEnabled(true)
            .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
            .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).setMaxRedirects(maxRedirects())
            .setSocketTimeout(socketTimeout()).setConnectTimeout(connectTimeout())
            .setConnectionRequestTimeout(requestTimeOut()).setRedirectsEnabled(followRedirects()).build();

    // Create an HttpClient with the given custom dependencies and
    // configuration.
    client = HttpClients.custom().setConnectionManager(connManager)
            // .setDefaultCredentialsProvider(credentialsProvider)
            .setDefaultRequestConfig(defaultRequestConfig).build();
}

From source file:com.github.lpezet.antiope.dao.DefaultHttpClientFactory.java

@Override
public HttpClient createHttpClient(APIConfiguration pConfiguration) {

    // Use a custom connection factory to customize the process of
    // initialization of outgoing HTTP connections. Beside standard connection
    // configuration parameters HTTP connection factory can define message
    // parser / writer routines to be employed by individual connections.
    HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> oConnFactory = new ManagedHttpClientConnectionFactory(
            new DefaultHttpRequestWriterFactory(), new DefaultHttpResponseParserFactory());

    SSLContext oSslContext = null;
    X509HostnameVerifier oHostnameVerifier = null;
    if (pConfiguration.isCheckSSLCertificates()) {
        oSslContext = SSLContexts.createSystemDefault();
        oHostnameVerifier = new BrowserCompatHostnameVerifier();
    } else {/*from   w  ww . j  a v a2 s.  co  m*/
        final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            @Override
            public void checkClientTrusted(final X509Certificate[] chain, final String authType) {
            }

            @Override
            public void checkServerTrusted(final X509Certificate[] chain, final String authType) {
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        } };

        // Install the all-trusting trust manager
        try {
            final SSLContext sslContext = SSLContext.getInstance(SSL);
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            // Create an ssl socket factory with our all-trusting manager
            //final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            oSslContext = sslContext;
        } catch (NoSuchAlgorithmException e) {
            throw new APIClientException(e);
        } catch (KeyManagementException e) {
            throw new APIClientException(e);
        }
        oHostnameVerifier = new AllowAllHostnameVerifier();
    }

    // Create a registry of custom connection socket factories for supported
    // protocol schemes.
    Registry<ConnectionSocketFactory> oSocketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register(HTTP, PlainConnectionSocketFactory.INSTANCE)
            .register(HTTPS, new SSLConnectionSocketFactory(oSslContext, oHostnameVerifier)).build();

    // Use custom DNS resolver to override the system DNS resolution.
    DnsResolver oDnsResolver = new SystemDefaultDnsResolver(); /* {
                                                               @Override
                                                               public InetAddress[] resolve(final String host) throws UnknownHostException {
                                                               if (host.equalsIgnoreCase("myhost")) {
                                                               return new InetAddress[] { InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }) };
                                                               } else {
                                                               return super.resolve(host);
                                                               }
                                                               }
                                                               };*/

    // Create a connection manager with custom configuration.
    PoolingHttpClientConnectionManager oConnManager = new PoolingHttpClientConnectionManager(
            oSocketFactoryRegistry, oConnFactory, oDnsResolver);

    // Create socket configuration
    SocketConfig oSocketConfig = SocketConfig.custom().setTcpNoDelay(true)
            .setSoTimeout(pConfiguration.getSocketTimeout()).build();

    // Configure the connection manager to use socket configuration either
    // by default or for a specific host.
    oConnManager.setDefaultSocketConfig(oSocketConfig);
    // connManager.setSocketConfig(new HttpHost("somehost", 80), oSocketConfig);

    // Create message constraints
    MessageConstraints oMessageConstraints = MessageConstraints.custom().setMaxHeaderCount(200)
            .setMaxLineLength(2000).build();
    // Create connection configuration
    ConnectionConfig oConnectionConfig = ConnectionConfig.custom()
            .setMalformedInputAction(CodingErrorAction.IGNORE)
            .setUnmappableInputAction(CodingErrorAction.IGNORE).setCharset(Consts.UTF_8)
            .setMessageConstraints(oMessageConstraints).build();
    // Configure the connection manager to use connection configuration either
    // by default or for a specific host.
    oConnManager.setDefaultConnectionConfig(oConnectionConfig);
    // connManager.setConnectionConfig(new HttpHost("somehost", 80), ConnectionConfig.DEFAULT);

    // Configure total max or per route limits for persistent connections
    // that can be kept in the pool or leased by the connection manager.
    oConnManager.setMaxTotal(100);
    oConnManager.setDefaultMaxPerRoute(10);
    //oConnManager.setMaxPerRoute(new HttpRoute(new HttpHost("somehost", 80)), 20);

    // Use custom cookie store if necessary.
    CookieStore oCookieStore = new BasicCookieStore();
    // Use custom credentials provider if necessary.
    //
    // Create global request configuration
    RequestConfig oDefaultRequestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.BEST_MATCH)
            //.setExpectContinueEnabled(true)         // WARNING: setting it to true slows things down by 4s!!!!
            .setStaleConnectionCheckEnabled(true)
            .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
            .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))
            .setConnectTimeout(pConfiguration.getConnectionTimeout()).build();

    CredentialsProvider oCredentialsProvider = new BasicCredentialsProvider();
    HttpHost oProxy = null;

    if (pConfiguration.getProxyHost() != null && pConfiguration.getProxyPort() > 0) {
        String proxyHost = pConfiguration.getProxyHost();
        int proxyPort = pConfiguration.getProxyPort();
        String proxyUsername = pConfiguration.getProxyUsername();
        String proxyPassword = pConfiguration.getProxyPassword();
        String proxyDomain = pConfiguration.getProxyDomain();
        String proxyWorkstation = pConfiguration.getProxyWorkstation();

        oProxy = new HttpHost(proxyHost, proxyPort);

        if (proxyUsername != null && proxyPassword != null) {
            oCredentialsProvider.setCredentials(new AuthScope(proxyHost, proxyPort),
                    new NTCredentials(proxyUsername, proxyPassword, proxyWorkstation, proxyDomain));
        }
    }

    // Create an HttpClient with the given custom dependencies and configuration.
    CloseableHttpClient oHttpClient = HttpClients.custom().setConnectionManager(oConnManager)
            .setDefaultCookieStore(oCookieStore).setDefaultCredentialsProvider(oCredentialsProvider)
            .setProxy(oProxy).setDefaultRequestConfig(oDefaultRequestConfig).build();

    return oHttpClient;
    /*
    RequestConfig oRequestConfig = RequestConfig.custom()
    .setConnectTimeout(pConfiguration.getConnectionTimeout())
    .setSocketTimeout(pConfiguration.getSocketTimeout())
    .setStaleConnectionCheckEnabled(true)
    .build();
    */
}

From source file:ch.cyberduck.core.http.HttpConnectionPoolBuilder.java

public HttpClientBuilder build(final TranscriptListener listener) {
    // Use HTTP Connect proxy implementation provided here instead of
    // relying on internal proxy support in socket factory
    final Proxy proxy = proxyFinder.find(host);
    if (proxy.getType() == Proxy.Type.HTTP) {
        final HttpHost h = new HttpHost(proxy.getHostname(), proxy.getPort(), Scheme.http.name());
        if (log.isInfoEnabled()) {
            log.info(String.format("Setup proxy %s", h));
        }//from w  w  w . j a v a  2  s .c  o  m
        builder.setProxy(h);
    }
    if (proxy.getType() == Proxy.Type.HTTPS) {
        final HttpHost h = new HttpHost(proxy.getHostname(), proxy.getPort(), Scheme.https.name());
        if (log.isInfoEnabled()) {
            log.info(String.format("Setup proxy %s", h));
        }
        builder.setProxy(h);
    }
    builder.setUserAgent(new PreferencesUseragentProvider().get());
    final int timeout = preferences.getInteger("connection.timeout.seconds") * 1000;
    builder.setDefaultSocketConfig(SocketConfig.custom().setTcpNoDelay(true).setSoTimeout(timeout).build());
    builder.setDefaultRequestConfig(RequestConfig.custom().setRedirectsEnabled(true)
            // Disable use of Expect: Continue by default for all methods
            .setExpectContinueEnabled(false).setAuthenticationEnabled(true).setConnectTimeout(timeout)
            // Sets the timeout in milliseconds used when retrieving a connection from the ClientConnectionManager
            .setConnectionRequestTimeout(preferences.getInteger("http.manager.timeout"))
            .setSocketTimeout(timeout).build());
    final String encoding;
    if (null == host.getEncoding()) {
        encoding = preferences.getProperty("browser.charset.encoding");
    } else {
        encoding = host.getEncoding();
    }
    builder.setDefaultConnectionConfig(
            ConnectionConfig.custom().setBufferSize(preferences.getInteger("http.socket.buffer"))
                    .setCharset(Charset.forName(encoding)).build());
    if (preferences.getBoolean("http.connections.reuse")) {
        builder.setConnectionReuseStrategy(new DefaultConnectionReuseStrategy());
    } else {
        builder.setConnectionReuseStrategy(new NoConnectionReuseStrategy());
    }
    builder.setRetryHandler(
            new ExtendedHttpRequestRetryHandler(preferences.getInteger("http.connections.retry")));
    if (!preferences.getBoolean("http.compression.enable")) {
        builder.disableContentCompression();
    }
    builder.setRequestExecutor(new LoggingHttpRequestExecutor(listener));
    // Always register HTTP for possible use with proxy. Contains a number of protocol properties such as the
    // default port and the socket factory to be used to create the java.net.Socket instances for the given protocol
    builder.setConnectionManager(this.pool(this.registry().build()));
    builder.setDefaultAuthSchemeRegistry(RegistryBuilder.<AuthSchemeProvider>create()
            .register(AuthSchemes.BASIC,
                    new BasicSchemeFactory(
                            Charset.forName(preferences.getProperty("http.credentials.charset"))))
            .register(AuthSchemes.DIGEST,
                    new DigestSchemeFactory(
                            Charset.forName(preferences.getProperty("http.credentials.charset"))))
            .register(AuthSchemes.NTLM, new NTLMSchemeFactory())
            .register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory())
            .register(AuthSchemes.KERBEROS, new KerberosSchemeFactory()).build());
    return builder;
}

From source file:plugins.KerberosSsoTest.java

/**
 * HTTP client that does not negotiate./*  w w  w . j a v a2s. co  m*/
 */
// I am not able to get the basic auth to work in FF 45.3.0, so using HttpClient instead
// org.openqa.selenium.UnsupportedCommandException: Unrecognized command: POST /session/466a800f-eaf8-40cf-a9e8-815f5a6e3c32/alert/credentials
// alert.setCredentials(new UserAndPassword("user", "ATH"));
private CloseableHttpClient getBadassHttpClient() {
    return HttpClientBuilder.create().setDefaultAuthSchemeRegistry(RegistryBuilder.<AuthSchemeProvider>create()
            .register(AuthSchemes.BASIC, new BasicSchemeFactory()).build()).build();
}

From source file:org.sdr.webrec.core.WebRec.java

private void initParameters() {

    // initialize HTTP parameters
    params = new BasicHttpParams();
    ConnManagerParams.setMaxTotalConnections(params, 100);
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);

    httpclient = new DefaultHttpClient(cm, params);

    //TODO: CloseableHttpClient httpclient = HttpClients.createDefault();

    //set proxy if available in settings
    if (settings.getProxyHost() != null && settings.getProxyHost().length() > 0) {
        HttpHost proxy = new HttpHost(settings.getProxyHost(), settings.getProxyPort());
        httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

        //set authentication to proxy is available is settings
        if (settings.getProxyUserName() != null && settings.getProxyUserName().length() > 0
                && settings.getProxyPasswd() != null) {
            httpclient.getCredentialsProvider().setCredentials(
                    new AuthScope(settings.getProxyHost(), settings.getProxyPort()),
                    new UsernamePasswordCredentials(settings.getProxyUserName(), settings.getProxyPasswd()));
            LOGGER.debug("autentication for proxy on");
        }//w w  w  . j av  a  2s  .c om

    }

    // initialize scheme registry 
    schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));

    // Create an HttpClient with the ThreadSafeClientConnManager.
    // This connection manager must be used if more than one thread will
    // be using the HttpClient.
    cm = new ThreadSafeClientConnManager(params, schemeRegistry);

    httpclient.setKeepAliveStrategy(new ConnectionKeepAliveStrategy() {

        public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
            // Honor 'keep-alive' header
            HeaderElementIterator it = new BasicHeaderElementIterator(
                    response.headerIterator(HTTP.CONN_KEEP_ALIVE));
            while (it.hasNext()) {
                HeaderElement he = it.nextElement();
                String param = he.getName();
                String value = he.getValue();
                if (value != null && param.equalsIgnoreCase("timeout")) {
                    try {
                        return Long.parseLong(value);
                    } catch (NumberFormatException ignore) {

                    }
                }
            }
            //otherwise keep alive for 30 seconds
            return 30 * 1000;
        }

    });

    httpget = null;

    httpclient = new DefaultHttpClient(cm, params);

    // Create global request configuration
    RequestConfig defaultRequestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.BEST_MATCH)
            .setExpectContinueEnabled(true).setStaleConnectionCheckEnabled(settings.isKeepConnectionAlive())
            .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
            .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build();

    requestConfig = RequestConfig.copy(defaultRequestConfig).setSocketTimeout(timeout)
            .setConnectTimeout(timeout).setConnectionRequestTimeout(timeout).build();

}

From source file:net.community.chest.gitcloud.facade.frontend.git.GitController.java

String authenticate(HttpServletRequest req) throws IOException {
    Principal principal = req.getUserPrincipal(); // check if already authenticated
    String username = (principal == null) ? null : principal.getName();
    if (!StringUtils.isEmpty(username)) {
        if (logger.isDebugEnabled()) {
            logger.debug("authenticate(" + req.getMethod() + ")[" + req.getRequestURI() + "]["
                    + req.getQueryString() + "]" + " using principal=" + username);
        }//from w ww  . ja  v a  2 s  . c om

        return username;
    }

    // TODO try to authenticate by cookie (if feature allowed) - see GitBlit#authenticate
    String authorization = StringUtils.trimToEmpty(req.getHeader(AUTH.WWW_AUTH_RESP));
    if (StringUtils.isEmpty(authorization)) {
        if (logger.isDebugEnabled()) {
            logger.debug("authenticate(" + req.getMethod() + ")[" + req.getRequestURI() + "]["
                    + req.getQueryString() + "] no authorization data");
        }
        return null;
    }

    // TODO add support for more authorization schemes - including password-less HTTP
    if (!authorization.startsWith(AuthSchemes.BASIC)) {
        logger.warn("authenticate(" + req.getMethod() + ")[" + req.getRequestURI() + "][" + req.getQueryString()
                + "]" + " unsupported authentication scheme: " + authorization);
        return null;
    }

    String b64Credentials = authorization.substring(AuthSchemes.BASIC.length()).trim();
    byte[] credBytes = Base64.decodeBase64(b64Credentials);
    String credentials = new String(credBytes, Charset.forName("UTF-8"));
    String[] credValues = StringUtils.split(credentials, ':');
    Validate.isTrue(credValues.length == 2, "Bad " + AuthSchemes.BASIC + " credentials format: %s",
            credentials);

    username = StringUtils.trimToEmpty(credValues[0]);
    String password = StringUtils.trimToEmpty(credValues[1]);
    if (authenticate(username, password)) {
        return username;
    } else {
        return null;
    }
}