com.swiftmq.net.HttpTunnelProperties Maven / Gradle / Ivy
/*
* Copyright 2019 IIT Software GmbH
*
* IIT Software GmbH 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
*
* 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.swiftmq.net;
import com.swiftmq.tools.prop.StructuredProperties;
import com.swiftmq.tools.prop.SystemProperties;
import com.swiftmq.tools.sql.LikeComparator;
import java.io.*;
import java.util.Base64;
import java.util.Properties;
import java.util.StringTokenizer;
// For documentation:
// HttpTunneling uses the CONNECT method. With this approach, a connection to a
// proxy is made, and after that a tunnel is established to the destination, tunneling starts. Often,
// the proxy allows only ports 443 and 563 for this tunnel, because this are the ports
// for SSL (SSL (https) will be tunneled exactly with this approach). Some proxies can
// be reconfigured, i. e. squid with "http_access deny CONNECT !Safe_ports" instead of
// "http_access deny CONNECT !SSL_ports". If this is not possible, the JMS listener must
// be defined on port 443 or 563.
public class HttpTunnelProperties implements Serializable {
public final static String PROP_FILENAME_PROP = "swiftmq.httptunnel.file";
public final static String PROP_DEBUG = "swiftmq.httptunnel.debug";
public final static String PROP_FILENAME = "/httptunnel.properties";
public final static String PROP_PROXY_HOST = "proxy.host";
public final static String PROP_PROXY_PORT = "proxy.port";
public final static String PROP_PROXY_USERNAME = "proxy.username";
public final static String PROP_PROXY_PASSWORD = "proxy.password";
public final static String PROP_NO_PROXY_HOST = "noproxy.host";
private String proxyHost = null;
private int proxyPort = -1;
private String username = null;
private String password = null;
private String[] excludeList = null;
private boolean debug = false;
private HttpTunnelProperties() {
try {
String sdebug = SystemProperties.get(PROP_DEBUG);
debug = sdebug != null && sdebug.equals("true");
InputStream in = null;
String filename = SystemProperties.get(PROP_FILENAME_PROP);
debug("Property filename = " + filename);
if (filename != null)
in = new FileInputStream(filename);
else
in = HttpTunnelProperties.class.getResourceAsStream(PROP_FILENAME);
debug((in == null ? "No property file found, HttpTunneling disabled" : "Property file found, HttpTunneling enabled"));
if (in == null)
return;
Properties prop = new Properties();
prop.load(in);
in.close();
debug("Properties = " + prop);
StructuredProperties sp = new StructuredProperties(prop);
proxyHost = prop.getProperty(PROP_PROXY_HOST);
proxyPort = Integer.parseInt(prop.getProperty(PROP_PROXY_PORT));
excludeList = sp.getSectionElements(PROP_NO_PROXY_HOST);
username = prop.getProperty(PROP_PROXY_USERNAME);
password = prop.getProperty(PROP_PROXY_PASSWORD);
} catch (Exception e) {
System.err.println("Exception during load of httptunnel properties: " + e);
}
}
public static HttpTunnelProperties getInstance() {
return InstanceHolder.instance;
}
private void debug(String msg) {
if (debug)
System.out.println("HttpTunneling: " + msg);
}
public void clear() {
proxyHost = null;
proxyPort = -1;
username = null;
password = null;
excludeList = null;
}
public void reload(Properties prop) {
if (debug)
System.out.println("reload: " + prop);
clear();
if (prop != null && prop.size() > 0) {
StructuredProperties sp = new StructuredProperties(prop);
proxyHost = prop.getProperty(PROP_PROXY_HOST);
proxyPort = Integer.parseInt(prop.getProperty(PROP_PROXY_PORT));
excludeList = sp.getSectionElements(PROP_NO_PROXY_HOST);
username = prop.getProperty(PROP_PROXY_USERNAME);
password = prop.getProperty(PROP_PROXY_PASSWORD);
}
}
public void reload(String filename) throws IOException {
if (debug)
System.out.println("reload from file: " + filename);
FileInputStream in = new FileInputStream(filename);
if (in == null)
throw new FileNotFoundException(filename);
Properties prop = new Properties();
prop.load(in);
reload(prop);
in.close();
}
public boolean isProxy() {
return proxyHost != null && proxyPort != -1;
}
public String getProxyHost() {
return (proxyHost);
}
public int getProxyPort() {
return (proxyPort);
}
public boolean isHostViaProxy(String hostname) {
debug("Checking, if host '" + hostname + "' goes through the proxy ...");
if (excludeList == null) {
debug("Yes (no exclude list defined)");
return true;
}
for (int i = 0; i < excludeList.length; i++) {
if (LikeComparator.compare(hostname, excludeList[i], '\\')) {
debug("No (matches for entry '" + excludeList[i] + "')");
return false;
}
}
debug("Yes (does not match any entry in the exclude list)");
return true;
}
// Does the necessary initial handling for HTTP 1.1 proxy connect
public void setupHttpProxy(String host, int port, InputStream socketInputStream, OutputStream socketOutputStream) throws IOException {
StringBuffer b = new StringBuffer("CONNECT ");
b.append(host);
b.append(':');
b.append(port);
b.append(" HTTP/1.0\r\nUser-Agent: SwiftMQ JMS Enterprise Messaging System\r\n");
if (username != null)
b.append("Proxy-Authorization: Basic " + (Base64.getEncoder().encodeToString((username + ":" + password).getBytes()) + "\r\n"));
b.append("\r\n");
debug("Sending to proxy: \n" + b.toString());
socketOutputStream.write(b.toString().getBytes());
socketOutputStream.flush();
String s = new String();
int c;
while ((c = socketInputStream.read()) != -1) {
s += String.valueOf((char) c);
if (s.endsWith("\r\n\r\n"))
break;
}
debug("Receiving from proxy: \n" + s);
StringTokenizer t = new StringTokenizer(s);
t.nextToken(); // skip http-version
String code = t.nextToken();
if (code.equals("200")) {
debug("Response from proxy is 200; tunneling starts ...");
return;
}
debug("Response from proxy is != 200; throwing exception");
throw new IOException("Error during proxy setup. Proxy responds with:\n" + s);
}
private static class InstanceHolder {
public static HttpTunnelProperties instance = new HttpTunnelProperties();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy