/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.core.util;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.AuthState;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.DigestScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.teiid.core.designer.util.Base64;
/**
* Helper class to build the URL objects from the strings. Since as an
* application we do not know if we are embedded or we are in our own server, we
* can not install the "URLStreamHandlers" in the VM, as they can be only
* installed once per VM, as an alternative, the stream handler must be
* specified at the time URL it is constructed. This class will help us to this
* code at one place. Here inspect the given string and build the correct type
* of URL with correct handler.
*
* @since 8.0
*/
public class URLHelper {
/**
* Construct the URL based on the String
*
* @param url
* @return
* @throws MalformedURLException
* @since 4.4
*/
public static URL buildURL(String url) throws MalformedURLException {
if (url == null)
throw new MalformedURLException();
url = convertBackSlashes(url);
final String filename = extractFileName(url);
if (filename != null) {
return new File(url).toURI().toURL();
}
return new URL(url);
}
public static URL buildURL(final URL url) {
try {
return buildURL(url.toExternalForm());
} catch (final MalformedURLException e) {
// since it came as url it should not have any issues with this
}
return null;
}
static String convertBackSlashes(final String str) {
return str.replaceAll("\\\\", "/"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Given an {@link URLConnection}, set its authorization property using the
* given username and password.
*
* @param urlConn
* @param userName
* @param password
*/
public static void setCredentials(URLConnection urlConn, String userName, String password) {
if (userName == null || password == null)
return;
if (!(urlConn instanceof HttpURLConnection)) {
// Should not be authenticating on other types of url connection
return;
}
urlConn.setRequestProperty("Authorization", //$NON-NLS-1$
"Basic " + Base64.encodeBytes((userName + ':' + password).getBytes())); //$NON-NLS-1$
}
/**
* Build a {@link java.io.File} from a {@link java.net.URL} object.
*
* @param url
* @param fileNamePrefix
* @param fileNameSuffix
* @return File
* @since 5.1
*/
public static File createFileFromUrl(final URL url, final String fileNamePrefix, final String fileNameSuffix)
throws MalformedURLException, IOException {
return createFileFromUrlInternal(url, FileUrl.createTempFile(fileNamePrefix, fileNameSuffix), null, null, true);
}
/**
* Build a {@link java.io.File} from a {@link java.net.URL} object.
*
* @param url
* @param fileNamePrefix
* @param fileNameSuffix
* @return File
* @since 5.1
*/
public static File createFileFromUrlwithDigest(final URL url, final String fileNamePrefix,
final String fileNameSuffix) throws MalformedURLException, IOException {
return createFileFromUrlInternalwithDigest(url, FileUrl.createTempFile(fileNamePrefix, fileNameSuffix), null,
null, true);
}
public static File createFileFromUrl(final URL url, final String fileNamePrefix, final String fileNameSuffix,
final String userName, final String password) throws MalformedURLException, IOException {
return createFileFromUrl(url, FileUrl.createTempFile(fileNamePrefix, fileNameSuffix).getAbsolutePath(),
userName, password, true);
}
/**
* Download the content from the given URL and save it into the specified
* file.
*
* @param url
* URL of the file to be saved
* @param filePath
* the full path of the file name
* @param userName
* user name if authentication is required
* @param password
* password if authentication is required
* @param verifyHostname
* whether to verify hostname for HTTPS connection
* @return the file created
* @throws MalformedURLException
* @throws IOException
* @since 5.5
*/
public static File createFileFromUrl(final URL url, final String filePath, final String userName,
final String password, final boolean verifyHostname) throws MalformedURLException, IOException {
File file = null;
final String tempDir = System.getProperty("java.io.tmpdir");//$NON-NLS-1$
if (filePath.indexOf("/") != -1 || filePath.indexOf("\\") != -1) {//$NON-NLS-1$//$NON-NLS-2$
int lastPart = filePath.lastIndexOf("/");//$NON-NLS-1$
if (lastPart == -1)
lastPart = filePath.lastIndexOf("\\");//$NON-NLS-1$
final String relativeDir = filePath.substring(0, lastPart);
final File dir = new File(new File(tempDir), relativeDir);
if (!dir.exists())
dir.mkdirs();
file = new File(dir, filePath.substring(lastPart + 1));
} else
file = new File(new File(tempDir), filePath);
return createFileFromUrlInternal(url, new FileUrl(file.toURI()), userName, password, verifyHostname);
}
private static File createFileFromUrlInternal(final URL url, final File file, final String userName,
final String password, final boolean verifyHostname) throws MalformedURLException, IOException {
URLConnection urlConn = null;
InputStreamReader inStream = null;
FileWriter fw = null;
BufferedWriter bw = null;
try {
file.deleteOnExit();
((FileUrl) file).setOriginalUrlString(url.toString());
fw = new FileWriter(file);
bw = new BufferedWriter(fw);
urlConn = url.openConnection();
setCredentials(urlConn, userName, password);
if (!verifyHostname && urlConn instanceof HttpsURLConnection)
((HttpsURLConnection) urlConn).setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(final String arg, final SSLSession session) {
return true;
}
});
inStream = new InputStreamReader(urlConn.getInputStream());
int c;
while ((c = inStream.read()) != -1) {
bw.write(c);
}
} finally {
if (inStream != null)
inStream.close();
if (bw != null)
bw.close();
}
return file;
}
private static File createFileFromUrlInternalwithDigest(final URL url, final File file, final String userName,
final String password, final boolean verifyHostname) throws MalformedURLException, IOException {
HttpHost target = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(target.getHostName(), target.getPort()),
new UsernamePasswordCredentials(userName, password));
CloseableHttpClient httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
try {
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate DIGEST scheme object, initialize it and add it to the
// local
// auth cache
DigestScheme digestAuth = new DigestScheme();
// Suppose we already know the realm name
// digestAuth.overrideParamter("realm", "some realm");
// Suppose we already know the expected nonce value
// digestAuth.overrideParamter("nonce", "whatever");
authCache.put(target, digestAuth);
// Add AuthCache to the execution context
HttpClientContext localContext = HttpClientContext.create();
localContext.setAuthCache(authCache);
HttpGet httpget = new HttpGet(url.toString());
System.out.println("Executing request " + httpget.getRequestLine() + " to target " + target);
for (int i = 0; i < 3; i++) {
CloseableHttpResponse response = httpclient.execute(httpget, localContext);
try {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
HttpEntity entity = response.getEntity();
InputStream instream = entity.getContent();
// Header contentCncoding = entity .getContentEncoding();
AuthState proxyAuthState = localContext.getProxyAuthState();
System.out.println("Proxy auth state: " + proxyAuthState.getState());
System.out.println("Proxy auth scheme: " + proxyAuthState.getAuthScheme());
System.out.println("Proxy auth credentials: " + proxyAuthState.getCredentials());
AuthState targetAuthState = localContext.getTargetAuthState();
System.out.println("Target auth state: " + targetAuthState.getState());
System.out.println("Target auth scheme: " + targetAuthState.getAuthScheme());
System.out.println("Target auth credentials: " + targetAuthState.getCredentials());
EntityUtils.consume(response.getEntity());
} finally {
response.close();
}
}
} finally {
httpclient.close();
}
// URLConnection urlConn = null;
// InputStreamReader inStream = null;
// FileWriter fw = null;
// BufferedWriter bw = null;
// try {
// file.deleteOnExit();
// ((FileUrl) file).setOriginalUrlString(url.toString());
// fw = new FileWriter(file);
// bw = new BufferedWriter(fw);
// urlConn = url.openConnection();
// setCredentials(urlConn, userName, password);
// if (!verifyHostname && urlConn instanceof HttpsURLConnection)
// ((HttpsURLConnection) urlConn).setHostnameVerifier(new
// HostnameVerifier() {
// @Override
// public boolean verify(final String arg, final SSLSession session) {
// return true;
// }
// });
// inStream = new InputStreamReader(urlConn.getInputStream());
// int c;
// while ((c = inStream.read()) != -1) {
// bw.write(c);
// }
//
// } finally {
// if (inStream != null)
// inStream.close();
// if (bw != null)
// bw.close();
// }
return file;
}
private HashMap<String, String> parseHeader(String headerString) {
// seperte out the part of the string which tells you which Auth scheme
// is it
String headerStringWithoutScheme = headerString.substring(headerString.indexOf(" ") + 1).trim();
HashMap<String, String> values = new HashMap<String, String>();
String keyValueArray[] = headerStringWithoutScheme.split(",");
for (String keyval : keyValueArray) {
if (keyval.contains("=")) {
String key = keyval.substring(0, keyval.indexOf("="));
String value = keyval.substring(keyval.indexOf("=") + 1);
values.put(key.trim(), value.replaceAll("\"", "").trim());
}
}
return values;
}
static String extractFileName(String file) {
if (file.matches("^(\\w){2,}:.*")) // Handles URLs - No //$NON-NLS-1$
// conversion necessary
// http://lib/foo.txt - currently do not support, converts to local
// host with absolute path
// file://lib/foo.txt
// file:///c:/lib/foo.txt
return null;
else if (file.matches("^\\/.*")) // Handles absolute //$NON-NLS-1$
// paths- it can be file or URL
// depending upon
// context Conversion needed
// /lib/foo.txt
return file;
else if (file.matches("^\\w:[\\\\,\\/].*")) { //$NON-NLS-1$
// Handles windows absolute path - no conversion needed
// c:\\lib\\foo.txt
// c:/lib.foo.txt
file = file.replaceAll("\\\\", "\\/"); //$NON-NLS-1$ //$NON-NLS-2$
return "/" + file; //$NON-NLS-1$
} else if (file.matches("^(\\.)+\\/.*|^\\w+\\/.*|^\\w+.*")) // Handles //$NON-NLS-1$
// relative
// paths -
// these can
// be URLs
// or files
// -
// conversion necessary
// ./lib/foo.txt
// ../lib/foo.txt
// lib/foo.txt
return file;
return null;
}
/**
* Determines whether a URL object resolves to a valid url. This will work
* for any protocol (file, HTTP, etc.).
*
* @param url
* @return resolved boolean
* @throws MalformedURLException,
* IOException
* @since 5.1
*/
public static boolean resolveUrl(final URL url) throws MalformedURLException, IOException {
return resolveUrl(url, true);
}
/**
* Determines whether a URL object resolves to a valid url. This will work
* for any protocol (file, HTTP, etc.).
*
* @param url
* @param verifyHostname
* whether to verify hostname for HTTPS connection
* @return resolved boolean
* @throws MalformedURLException,
* IOException
* @since 5.5
*/
public static boolean resolveUrl(final URL url, final boolean verifyHostname)
throws MalformedURLException, IOException {
return resolveUrl(url, null, null, null, verifyHostname);
}
/**
* Determines whether a URL object resolves to a valid url. This will work
* for any protocol (file, HTTP, etc.).
*
* @param url
* @param userName
* @param password
* @param connRequestPropMap
* Map of Connection RequestProperties
* @param verifyHostname
* whether to verify hostname for HTTPS connection
* @return resolved boolean
* @throws MalformedURLException,
* IOException
* @since 5.1
*/
public static boolean resolveUrl(final URL url, final String userName, final String password,
final Map<String, String> connRequestPropMap, final boolean verifyHostname)
throws MalformedURLException, IOException {
boolean resolved = true;
if (url == null)
return resolved;
String nextLine;
URLConnection urlConn = null;
InputStreamReader inStream = null;
BufferedReader buff = null;
// Add a time-out here....
final long timeOut = 30000;
final long startTime = System.currentTimeMillis();
long deltaTime = 0;
try {
urlConn = url.openConnection();
setCredentials(urlConn, userName, password);
if (!verifyHostname && urlConn instanceof HttpsURLConnection)
((HttpsURLConnection) urlConn).setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(final String arg, final SSLSession session) {
return true;
}
});
// Set any request properties
urlConn.setDoInput(true);
if (connRequestPropMap != null) {
for (String propName : connRequestPropMap.keySet()) {
urlConn.setRequestProperty(propName, connRequestPropMap.get(propName));
}
}
inStream = new InputStreamReader(urlConn.getInputStream());
buff = new BufferedReader(inStream);
boolean keepReading = true;
// Read and print the lines from index.html
while (keepReading) {
nextLine = buff.readLine();
if (nextLine != null) {
} else
break;
deltaTime = System.currentTimeMillis() - startTime;
if (deltaTime > timeOut) {
keepReading = false;
resolved = false;
}
}
} finally {
if (inStream != null)
inStream.close();
}
return resolved;
}
/**
* Determines whether a URL object resolves to a valid url. This will work
* for any protocol (file, HTTP, etc.).
*
* @param url
* @param userName
* @param password
* @param connRequestPropMap
* Map of Connection RequestProperties
* @param verifyHostname
* whether to verify hostname for HTTPS connection
* @return resolved boolean
* @throws Exception
* @since 5.1
*/
public static boolean resolveUrlWithDigest(final URL url, final String userName, final String password,
final Map<String, String> connRequestPropMap, final boolean verifyHostname)
throws Exception {
boolean resolved = true;
if (url == null)
return resolved;
resolved = resolveDigest(url, userName, password, resolved);
return resolved;
}
/**
* @param url
* @param userName
* @param password
* @param resolved
* @return
* @throws IOException
* @throws ClientProtocolException
* @throws Exception
*/
private static boolean resolveDigest(final URL url, final String userName, final String password, boolean resolved)
throws IOException, ClientProtocolException, Exception {
HttpHost target = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(target.getHostName(), target.getPort()),
new UsernamePasswordCredentials(userName, password));
CloseableHttpClient httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
try {
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate DIGEST scheme object, initialize it and add it to the
// local
// auth cache
DigestScheme digestAuth = new DigestScheme();
authCache.put(target, digestAuth);
// Create and add a CookieStore in case the service requires a
// cookie (and who doesn't require a cookie? Mmmm.. cookies).
CookieStore cookieStore = new BasicCookieStore();
httpclient = HttpClients.custom().setDefaultCookieStore(cookieStore)
.setDefaultCredentialsProvider(credsProvider).build();
// Add AuthCache to the execution context
HttpClientContext localContext = HttpClientContext.create();
localContext.setAuthCache(authCache);
HttpGet httpget = new HttpGet(url.toString());
CloseableHttpResponse response = httpclient.execute(httpget, localContext);
try {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (response.getStatusLine().getStatusCode()!=200){
resolved = false;
throw new Exception(response.getStatusLine().getReasonPhrase());
}
HttpEntity entity = response.getEntity();
AuthState proxyAuthState = localContext.getProxyAuthState();
AuthState targetAuthState = localContext.getTargetAuthState();
EntityUtils.consume(response.getEntity());
} finally {
response.close();
}
} finally {
httpclient.close();
}
return resolved;
}
/**
* @param url
* @param userName
* @param password
* @param resolved
* @return
* @throws IOException
* @throws ClientProtocolException
* @throws Exception
*/
public static InputStream getWSDLWithDigest(final URL url, final String userName, final String password)
throws IOException, ClientProtocolException, Exception {
HttpHost target = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(target.getHostName(), target.getPort()),
new UsernamePasswordCredentials(userName, password));
CloseableHttpClient httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
CloseableHttpResponse response = null;
try {
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate DIGEST scheme object, initialize it and add it to the
// local
// auth cache
DigestScheme digestAuth = new DigestScheme();
authCache.put(target, digestAuth);
// Create and add a CookieStore in case the service requires a
// cookie (and who doesn't require a cookie? Mmmm.. cookies).
CookieStore cookieStore = new BasicCookieStore();
httpclient = HttpClients.custom().setDefaultCookieStore(cookieStore)
.setDefaultCredentialsProvider(credsProvider).build();
// Add AuthCache to the execution context
HttpClientContext localContext = HttpClientContext.create();
localContext.setAuthCache(authCache);
HttpGet httpget = new HttpGet(url.toString());
response = httpclient.execute(httpget, localContext);
try {
if (response.getStatusLine().getStatusCode()!=200){
throw new Exception(response.getStatusLine().getReasonPhrase());
}
HttpEntity entity = response.getEntity();
AuthState proxyAuthState = localContext.getProxyAuthState();
AuthState targetAuthState = localContext.getTargetAuthState();
} finally {
response.close();
}
} finally {
httpclient.close();
}
return response.getEntity().getContent();
}
}