    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/framework/util/HttpUtils.java $
    002    /*----------------    FILE HEADER  ------------------------------------------
    003     This file is part of deegree.
    004     Copyright (C) 2001-2008 by:
    005     Department of Geography, University of Bonn
    006     http://www.giub.uni-bonn.de/deegree/
    007     lat/lon GmbH
    008     http://www.lat-lon.de
    009
    010     This library is free software; you can redistribute it and/or
    011     modify it under the terms of the GNU Lesser General Public
    012     License as published by the Free Software Foundation; either
    013     version 2.1 of the License, or (at your option) any later version.
    014     This library is distributed in the hope that it will be useful,
    015     but WITHOUT ANY WARRANTY; without even the implied warranty of
    016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    017     Lesser General Public License for more details.
    018     You should have received a copy of the GNU Lesser General Public
    019     License along with this library; if not, write to the Free Software
    020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    021     Contact:
    022
    023     Andreas Poth
    024     lat/lon GmbH
    025     Aennchenstr. 19
    026     53177 Bonn
    027     Germany
    028     E-Mail: poth@lat-lon.de
    029
    030     Prof. Dr. Klaus Greve
    031     Department of Geography
    032     University of Bonn
    033     Meckenheimer Allee 166
    034     53115 Bonn
    035     Germany
    036     E-Mail: greve@giub.uni-bonn.de
    037     ---------------------------------------------------------------------------*/
    038
    039    package org.deegree.framework.util;
    040
    041    import java.io.ByteArrayOutputStream;
    042    import java.io.IOException;
    043    import java.io.InputStream;
    044    import java.net.HttpURLConnection;
    045    import java.net.InetAddress;
    046    import java.net.MalformedURLException;
    047    import java.net.URISyntaxException;
    048    import java.net.URL;
    049    import java.util.Map;
    050    import java.util.Properties;
    051
    052    import javax.xml.transform.OutputKeys;
    053
    054    import org.apache.commons.codec.binary.Base64;
    055    import org.apache.commons.httpclient.HttpClient;
    056    import org.apache.commons.httpclient.HttpException;
    057    import org.apache.commons.httpclient.HttpMethod;
    058    import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
    059    import org.apache.commons.httpclient.methods.GetMethod;
    060    import org.apache.commons.httpclient.methods.HeadMethod;
    061    import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
    062    import org.apache.commons.httpclient.methods.PostMethod;
    063    import org.apache.commons.httpclient.methods.StringRequestEntity;
    064    import org.deegree.enterprise.WebUtils;
    065    import org.deegree.framework.log.ILogger;
    066    import org.deegree.framework.log.LoggerFactory;
    067    import org.deegree.framework.xml.XMLFragment;
    068
    069    /**
    070     * utility class for performing HTTP requests
    071     *
    072     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
    073     * @author last edited by: $Author: apoth $
    074     *
    075     * @version. $Revision: 25236 $, $Date: 2010-07-09 11:29:33 +0200 (Fr, 09. Jul 2010) $
    076     */
    077    public class HttpUtils {
    078
    079        private static final ILogger LOG = LoggerFactory.getLogger( HttpUtils.class );
    080
    081        /**
    082         * validates passed URL. If it is not a valid URL or a client can not connect to it an exception will be thrown
    083         *
    084         * @param url
    085         * @throws IOException
    086         */
    087        public static int validateURL( String url )
    088                                throws IOException {
    089            return validateURL( url, null, null );
    090        }
    091
    092        /**
    093         * validates passed URL. If it is not a valid URL or a client can not connect to it an exception will be thrown
    094         *
    095         * @param url
    096         * @param user
    097         * @param password
    098         * @throws IOException
    099         */
    100        public static int validateURL( String url, String user, String password )
    101                                throws IOException {
    102            if ( url.startsWith( "http:" ) ) {
    103                URL tmp = new URL( url );
    104                HeadMethod hm = new HeadMethod( url );
    105                setHTTPCredentials( hm, user, password );
    106                InetAddress.getByName( tmp.getHost() );
    107                HttpClient client = new HttpClient();
    108                client.executeMethod( hm );
    109                if ( hm.getStatusCode() != HttpURLConnection.HTTP_OK ) {
    110                    if ( hm.getStatusCode() != HttpURLConnection.HTTP_UNAUTHORIZED && hm.getStatusCode() != 401 ) {
    111                        // this method just evaluates if a URL/host is valid; it does not takes care
    112                        // if authorization is available/valid
    113                        throw new IOException( "Host " + tmp.getHost() + " of URL + " + url + " does not exists" );
    114                    }
    115                }
    116                return hm.getStatusCode();
    117            } else if ( url.startsWith( "file:" ) ) {
    118                URL tmp = new URL( url );
    119                InputStream is = tmp.openStream();
    120                is.close();
    121                return 200;
    122            }
    123            return HttpURLConnection.HTTP_UNAVAILABLE;
    124        }
    125
    126        /**
    127         *
    128         * @param url
    129         * @param content
    130         * @param timeout
    131         *            timeout in milliseconds
    132         * @param user
    133         *            (can be <code>null</code>)
    134         * @param password
    135         *            (can be <code>null</code>)
    136         * @param contentType
    137         *            request content mime type (can be <code>null</code>)
    138         * @param encoding
    139         *            request encoding (can be <code>null</code>)
    140         * @param header
    141         *            not supported yet
    142         * @return result of http post request
    143         * @throws HttpException
    144         * @throws IOException
    145         */
    146        public static HttpMethod performHttpPost( String url, InputStream content, int timeout, String user,
    147                                                  String password, String contentType, String encoding,
    148                                                  Map<String, String> header )
    149                                throws HttpException, IOException {
    150            HttpClient client = new HttpClient();
    151            URL tmp = new URL( url );
    152            WebUtils.enableProxyUsage( client, tmp );
    153            url = tmp.toExternalForm();
    154            client.getHttpConnectionManager().getParams().setSoTimeout( timeout );
    155            client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout );
    156
    157            PostMethod pm = new PostMethod( url );
    158            String ct = contentType;
    159            if ( ct != null && encoding != null ) {
    160                ct += ( "; " + encoding );
    161            }
    162            if ( ct != null ) {
    163                pm.setRequestEntity( new InputStreamRequestEntity( content, ct ) );
    164            } else {
    165                pm.setRequestEntity( new InputStreamRequestEntity( content ) );
    166            }
    167
    168            setHTTPCredentials( pm, user, password );
    169            client.executeMethod( pm );
    170            if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
    171                LOG.logDebug( pm.getResponseBodyAsString() );
    172            }
    173            if ( pm.getStatusCode() != 200 ) {
    174                throw new HttpException( "status code: " + pm.getStatusCode() );
    175            }
    176            return pm;
    177        }
    178
    179        /**
    180         *
    181         * @param url
    182         * @param content
    183         * @param timeout
    184         *            timeout in milliseconds
    185         * @param user
    186         *            (can <code>null</code>)
    187         * @param password
    188         *            (can <code>null</code>)
    189         * @param contentType
    190         *            request content mime type (can be <code>null</code>)
    191         * @param encoding
    192         *            request encoding (can be <code>null</code>)
    193         * @param header
    194         *            not supported yet
    195         * @return result of http post request
    196         * @throws HttpException
    197         * @throws IOException
    198         */
    199        public static HttpMethod performHttpPost( String url, String content, int timeout, String user, String password,
    200                                                  String contentType, String encoding, Map<String, String> header )
    201                                throws HttpException, IOException {
    202            HttpClient client = new HttpClient();
    203            URL tmp = new URL( url );
    204            WebUtils.enableProxyUsage( client, tmp );
    205            url = tmp.toExternalForm();
    206            client.getHttpConnectionManager().getParams().setSoTimeout( timeout );
    207            client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout );
    208            PostMethod pm = new PostMethod( url );
    209
    210            pm.setRequestEntity( new StringRequestEntity( content, contentType, encoding ) );
    211
    212            setHTTPCredentials( pm, user, password );
    213            client.executeMethod( pm );
    214            if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
    215                LOG.logDebug( pm.getResponseBodyAsString() );
    216            }
    217            if ( pm.getStatusCode() != 200 ) {
    218                throw new HttpException( "status code: " + pm.getStatusCode() );
    219            }
    220            return pm;
    221        }
    222
    223        /**
    224         *
    225         * @param url
    226         * @param content
    227         * @param timeout
    228         *            timeout in milliseconds
    229         * @param user
    230         *            (can <code>null</code>)
    231         * @param password
    232         *            (can <code>null</code>)
    233         * @param header
    234         *            not supported yet
    235         * @return result of http post request
    236         * @throws HttpException
    237         * @throws IOException
    238         */
    239        public static HttpMethod performHttpPost( String url, XMLFragment content, int timeout, String user, String password,
    240                                                  Map<String, String> header )
    241                                throws HttpException, IOException {
    242            HttpClient client = new HttpClient();
    243            URL tmp = new URL( url );
    244            WebUtils.enableProxyUsage( client, tmp );
    245            url = tmp.toExternalForm();
    246            client.getHttpConnectionManager().getParams().setSoTimeout( timeout );
    247            client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout );
    248            PostMethod pm = new PostMethod( url );
    249
    250            ByteArrayOutputStream bos = new ByteArrayOutputStream( 1000000 );
    251            Properties props = new Properties();
    252            props.put( OutputKeys.ENCODING, "UTF-8" );
    253            content.write( bos, props );
    254            bos.close();
    255            pm.setRequestEntity( new ByteArrayRequestEntity( bos.toByteArray(), "text/xml" ) );
    256
    257            setHTTPCredentials( pm, user, password );
    258            client.executeMethod( pm );
    259            if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
    260                LOG.logDebug( pm.getResponseBodyAsString() );
    261            }
    262            if ( pm.getStatusCode() != 200 ) {
    263                throw new HttpException( "status code: " + pm.getStatusCode() );
    264            }
    265            return pm;
    266        }
    267
    268        /**
    269         *
    270         * @param url
    271         *            e.g. http://localhost:8080/deegree/services
    272         * @param request
    273         *            e.g. service=WMS&request=GetCapabilities
    274         * @param timeout
    275         *            timeout in milliseconds
    276         * @param user
    277         *            (can be <code>null</code>)
    278         * @param password
    279         *            (can be <code>null</code>)
    280         * @param header
    281         *            (not supported yet)
    282         * @return result of http get request
    283         * @throws HttpException
    284         * @throws IOException
    285         */
    286        public static HttpMethod performHttpGet( String url, String request, int timeout, String user, String password,
    287                                                 Map<String, String> header )
    288                                throws HttpException, IOException {
    289            if ( request != null && request.startsWith( "&" ) ) {
    290                request = request.substring( 1 );
    291            }
    292            if ( url != null && url.endsWith( "?" ) ) {
    293                url = url.substring( 0, url.length() - 1 );
    294            }
    295            LOG.logDebug( "HTTP GET URL: ", url );
    296            LOG.logDebug( "HTTP GET request: ", request );
    297            GetMethod gm = null;
    298            if ( url.indexOf( '?' ) > -1 && request != null ) {
    299                gm = new GetMethod( StringTools.concat( 500, url, '&', request ) );
    300            } else if ( request != null && !request.startsWith( "http://" ) ) {
    301                gm = new GetMethod( StringTools.concat( 500, url, '?', request ) );
    302            } else if ( request != null && request.startsWith( "http://" ) ) {
    303                gm = new GetMethod( request );
    304            } else {
    305                gm = new GetMethod( url );
    306            }
    307
    308            setHTTPCredentials( gm, user, password );
    309
    310            HttpClient client = new HttpClient();
    311            client.getHttpConnectionManager().getParams().setSoTimeout( timeout );
    312            client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout );
    313            WebUtils.enableProxyUsage( client, new URL( url ) );
    314            client.executeMethod( gm );
    315            if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
    316                LOG.logDebug( gm.getResponseBodyAsString() );
    317            }
    318            if ( gm.getStatusCode() != 200 ) {
    319                throw new HttpException( "status code: " + gm.getStatusCode() );
    320            }
    321            return gm;
    322        }
    323
    324        /**
    325         *
    326         * @param url
    327         * @param user
    328         * @param password
    329         * @param sessionID
    330         * @return URL with attached authentication information (if not null)
    331         */
    332        public static String addAuthenticationForKVP( String url, String user, String password, String sessionID ) {
    333            if ( sessionID != null && sessionID.trim().length() > 0 ) {
    334                url = url + "&sessionID=" + sessionID;
    335            } else if ( user != null ) {
    336                url = url + "&user=" + user;
    337                if ( password == null ) {
    338                    password = "";
    339                }
    340                url = url + "&password=" + password;
    341            }
    342            return url;
    343        }
    344
    345        /**
    346         *
    347         * @param xml
    348         * @param user
    349         * @param password
    350         * @param sessionID
    351         * @return XML document with authentication information (if not null) as attributes of the root element
    352         */
    353        public static XMLFragment addAuthenticationForXML( XMLFragment xml, String user, String password, String sessionID ) {
    354            if ( sessionID != null ) {
    355                xml.getRootElement().setAttribute( "sessionID", sessionID );
    356            } else if ( user != null ) {
    357                xml.getRootElement().setAttribute( "user", user );
    358                if ( password != null ) {
    359                    xml.getRootElement().setAttribute( "password", password );
    360                }
    361            }
    362            return xml;
    363        }
    364
    365        /**
    366         *
    367         * @param url
    368         * @return URL as String with protocol and path but without request params
    369         * @throws URISyntaxException
    370         */
    371        public static String normalizeURL( URL url ) {
    372            String pr = url.getProtocol();
    373            String ho = url.getHost();
    374            int po = url.getPort();
    375            String pa = url.getPath();
    376            String s = pr + "://" + ho + ':' + po;
    377            if ( pa != null && pa.length() > 0 ) {
    378                s += pa;
    379            }
    380            return s;
    381        }
    382
    383        /**
    384         *
    385         * @param url
    386         * @return URL as String with protocol and path but without request params
    387         * @throws URISyntaxException
    388         */
    389        public static String normalizeURL( String url ) {
    390            try {
    391                return normalizeURL( new URL( url ) );
    392            } catch ( MalformedURLException e ) {
    393                LOG.logWarning( e.getMessage(), e );
    394            }
    395            return url;
    396        }
    397
    398        private static void setHTTPCredentials( HttpMethod m, String user, String password ) {
    399            if ( user != null ) {
    400                if ( password == null ) {
    401                    password = "";
    402                }
    403                String s = new String( Base64.encodeBase64( ( user + ":" + password ).getBytes() ) );
    404                m.setRequestHeader( "authorization", "Basic " + s );
    405            }
    406        }
    407
    408    }