/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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.
*
* Copyright (c) 2015 Pentaho Corporation. All rights reserved.
*/
package org.pentaho.marketplace.util.web;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.SimpleHttpConnectionManager;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
public class HttpUtil {
private static final String PROXY_HOST_PROPERTY_NAME = "http.proxyHost";
private static final String PROXY_PORT_PROPERTY_NAME = "http.proxyPort";
private static final String PROXY_USER_PROPERTY_NAME = "http.proxyUser";
private static final String PROXY_PASSWORD_PROPERTY_NAME = "http.proxyPassword";
private static Log logger = LogFactory.getLog( HttpUtil.class );
public static HttpClient getClient() {
int connectionTimeout = 3000;
int pageTimeout = 7000;
HttpConnectionManager connectionManager = new SimpleHttpConnectionManager();
HttpConnectionManagerParams connectionParams = connectionManager.getParams();
connectionParams.setConnectionTimeout( connectionTimeout );
connectionParams.setSoTimeout( pageTimeout );
HttpClient httpClient = null;
if ( connectionManager != null ) {
httpClient = new HttpClient( connectionManager );
}
try {
HostConfiguration hostConfig = null;
final String proxyHost = System.getProperty( PROXY_HOST_PROPERTY_NAME );
final int proxyPort = Integer.parseInt( System.getProperty( PROXY_PORT_PROPERTY_NAME ) );
if ( StringUtils.isNotEmpty( proxyHost ) ) {
hostConfig = new HostConfiguration() {
@Override
public synchronized String getProxyHost() {
return proxyHost;
}
@Override
public synchronized int getProxyPort() {
return proxyPort;
}
};
httpClient.setHostConfiguration( hostConfig );
String proxyUser = System.getProperty( PROXY_USER_PROPERTY_NAME );
String proxyPassword = System.getProperty( PROXY_PASSWORD_PROPERTY_NAME );
if ( proxyUser != null && proxyUser.trim().length() > 0 ) {
httpClient.getState().setProxyCredentials(
new AuthScope( proxyHost, proxyPort ),
new UsernamePasswordCredentials( proxyUser, proxyPassword )
);
}
}
} catch ( Exception ignored ) { }
return httpClient;
}
public static boolean getURLContent( final String url, final StringBuffer content ) {
InputStream response = getURLInputStream( url );
if ( response == null ) {
return false;
}
try {
byte[] buffer = new byte[ 2048 ];
int size = response.read( buffer );
while ( size > 0 ) {
for ( int idx = 0; idx < size; idx++ ) {
content.append( (char) buffer[ idx ] );
}
size = response.read( buffer );
}
} catch ( Exception e ) {
// we can ignore this because the content comparison will fail
}
return true;
}
public static String getURLContent( final String uri ) {
StringBuffer content = new StringBuffer();
HttpUtil.getURLContent( uri, content );
return content.toString();
}
public static InputStream getURLInputStream( final String url ) {
HttpClient httpClient = HttpUtil.getClient();
try {
GetMethod call = new GetMethod( url );
call.setFollowRedirects( true );
int status = httpClient.executeMethod( call );
if ( status == 200 ) {
return call.getResponseBodyAsStream();
}
return null;
} catch ( Throwable e ) {
logger.debug( "Unable to get input stream from " + url, e );
return null;
}
}
public static InputStream getURLInputStream( final URL url ) {
return getURLInputStream( url.toString() );
}
public static Reader getURLReader( final String uri ) {
InputStream inputStream = getURLInputStream( uri );
if ( inputStream != null ) {
return new InputStreamReader( inputStream );
}
return null;
}
//
// The code in the next two methods is based on the code in HttpUtils.java
// from
// javax.servlet.http. HttpUtils is deprecated - so I updated the methods to
// be a bit smarter
// and use Map instead of Hashtable
//
public static Map parseQueryString( final String s ) {
String[] valArray = null;
if ( s == null ) {
throw new IllegalArgumentException();
}
Map<String, String[]> rtn = new HashMap<String, String[]>();
StringBuffer sb = new StringBuffer();
String key;
for ( StringTokenizer st = new StringTokenizer( s, "&" ); st.hasMoreTokens();
rtn.put( key, valArray ) ) { //$NON-NLS-1$
String pair = st.nextToken();
int pos = pair.indexOf( '=' );
if ( pos == -1 ) {
throw new IllegalArgumentException();
}
key = HttpUtil.parseName( pair.substring( 0, pos ), sb );
String val = HttpUtil.parseName( pair.substring( pos + 1, pair.length() ), sb );
if ( rtn.containsKey( key ) ) {
String[] oldVals = rtn.get( key );
valArray = new String[ oldVals.length + 1 ];
System.arraycopy( oldVals, 0, valArray, 0, oldVals.length );
valArray[ oldVals.length ] = val;
} else {
valArray = new String[ 1 ];
valArray[ 0 ] = val;
}
}
return rtn;
}
private static String parseName( final String s, final StringBuffer sb ) {
sb.setLength( 0 );
char c;
for ( int i = 0; i < s.length(); i++ ) {
c = s.charAt( i );
switch ( c ) {
case 43: { // '+'
sb.append( ' ' );
break;
}
case 37: { // '%'
try {
sb.append( (char) Integer.parseInt( s.substring( i + 1, i + 3 ), 16 ) );
i += 2;
break;
} catch ( NumberFormatException numberformatexception ) {
throw new IllegalArgumentException();
} catch ( StringIndexOutOfBoundsException oob ) {
String rest = s.substring( i );
sb.append( rest );
if ( rest.length() == 2 ) {
i++;
}
}
break;
}
default: {
sb.append( c );
break;
}
}
}
return sb.toString();
}
}