org.exist.xquery.modules.httpclient.HTTPClientModule.java Source code

Java tutorial

Introduction

Here is the source code for org.exist.xquery.modules.httpclient.HTTPClientModule.java

Source

/*
 * eXist Open Source Native XML Database
 * Copyright (C) 2007-2009 The eXist Project
 * http://exist-db.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 *  $Id$
 */
package org.exist.xquery.modules.httpclient;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.exist.xquery.AbstractInternalModule;
import org.exist.xquery.FunctionDef;

/**
 * HTTPClient module
 *
 * @author   Adam Retter <adam.retter@devon.gov.uk>
 * @author   Andrzej Taramina <andrzej@chaeron.com>
 * @author   ljo
 * @version  1.3
 * @serial   20100228
 */
public class HTTPClientModule extends AbstractInternalModule {
    private final static Logger LOG = LogManager.getLogger(HTTPClientModule.class);

    public final static String NAMESPACE_URI = "http://exist-db.org/xquery/httpclient";

    public final static String PREFIX = "httpclient";
    public final static String INCLUSION_DATE = "2007-09-06";
    public final static String RELEASED_IN_VERSION = "eXist-1.2";

    public final static String HTTP_MODULE_PERSISTENT_STATE = "_eXist_httpclient_module_persistent_state";
    public final static String HTTP_MODULE_PERSISTENT_OPTIONS = "_eXist_httpclient_module_persistent_options";

    final static HttpClient httpClient = setupHttpClient();

    private final static FunctionDef[] functions = { new FunctionDef(GETFunction.signatures[0], GETFunction.class),
            new FunctionDef(GETFunction.signatures[1], GETFunction.class),
            new FunctionDef(PUTFunction.signatures[0], PUTFunction.class),
            new FunctionDef(PUTFunction.signatures[1], PUTFunction.class),
            new FunctionDef(DELETEFunction.signature, DELETEFunction.class),
            new FunctionDef(POSTFunction.signatures[0], POSTFunction.class),
            new FunctionDef(POSTFunction.signatures[1], POSTFunction.class),
            new FunctionDef(HEADFunction.signature, HEADFunction.class),
            new FunctionDef(OPTIONSFunction.signature, OPTIONSFunction.class),
            new FunctionDef(ClearFunction.signatures[0], ClearFunction.class),
            new FunctionDef(SetOptionsFunction.signatures[0], SetOptionsFunction.class) };

    public HTTPClientModule(Map<String, List<? extends Object>> parameters) {
        super(functions, parameters);
    }

    public String getNamespaceURI() {
        return (NAMESPACE_URI);
    }

    public String getDefaultPrefix() {
        return (PREFIX);
    }

    public String getDescription() {
        return ("A module for performing HTTP requests as a client");
    }

    public String getReleaseVersion() {
        return (RELEASED_IN_VERSION);
    }

    private static HttpClient setupHttpClient() {
        final HttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
        final HttpClient client = new HttpClient(httpConnectionManager);

        //config from file if present
        final String configFile = System.getProperty("http.configfile");
        if (configFile != null) {
            final Path f = Paths.get(configFile);
            if (Files.exists(f)) {
                setConfigFromFile(f, client);
            } else {
                LOG.warn("http.configfile '" + f.toAbsolutePath() + "' does not exist!");
            }
        }

        // Legacy: set the proxy server (if any) from system properties
        final String proxyHost = System.getProperty("http.proxyHost");
        if (proxyHost != null) {
            //TODO: support for http.nonProxyHosts e.g. -Dhttp.nonProxyHosts="*.devonline.gov.uk|*.devon.gov.uk"
            final ProxyHost proxy = new ProxyHost(proxyHost,
                    Integer.parseInt(System.getProperty("http.proxyPort")));
            client.getHostConfiguration().setProxyHost(proxy);
        }

        return client;
    }

    private static void setConfigFromFile(final Path configFile, final HttpClient http) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("http.configfile='" + configFile.toAbsolutePath() + "'");
        }

        final Properties props = new Properties();
        try (final InputStream is = Files.newInputStream(configFile)) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Loading proxy settings from " + configFile.toAbsolutePath());
            }

            props.load(is);

            // Hostname / port
            final String proxyHost = props.getProperty("proxy.host");
            final int proxyPort = Integer.parseInt(props.getProperty("proxy.port", "8080"));

            // Username / password
            final String proxyUser = props.getProperty("proxy.user");
            final String proxyPassword = props.getProperty("proxy.password");

            // NTLM specifics
            String proxyDomain = props.getProperty("proxy.ntlm.domain");
            if ("NONE".equalsIgnoreCase(proxyDomain)) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Forcing removal NTLM");
                }
                proxyDomain = null;
            }

            // Set scope
            final AuthScope authScope = new AuthScope(proxyHost, proxyPort);

            // Setup right credentials
            final Credentials credentials;
            if (proxyDomain == null) {
                credentials = new UsernamePasswordCredentials(proxyUser, proxyPassword);
            } else {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Using NTLM authentication for '" + proxyDomain + "'");
                }
                credentials = new NTCredentials(proxyUser, proxyPassword, proxyHost, proxyDomain);
            }

            // Set details
            final HttpState state = http.getState();
            http.getHostConfiguration().setProxy(proxyHost, proxyPort);
            state.setProxyCredentials(authScope, credentials);

            if (LOG.isDebugEnabled()) {
                LOG.info("Set proxy: " + proxyUser + "@" + proxyHost + ":" + proxyPort
                        + (proxyDomain == null ? "" : " (NTLM:'" + proxyDomain + "')"));
            }
        } catch (final IOException ex) {
            LOG.error("Failed to read proxy configuration from '" + configFile + "'");
        }
    }
}