001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_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.Iterator; 050 import java.util.Map; 051 import java.util.Properties; 052 053 import javax.xml.transform.OutputKeys; 054 055 import org.apache.commons.codec.binary.Base64; 056 import org.apache.commons.httpclient.Header; 057 import org.apache.commons.httpclient.HttpClient; 058 import org.apache.commons.httpclient.HttpException; 059 import org.apache.commons.httpclient.HttpMethod; 060 import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; 061 import org.apache.commons.httpclient.methods.GetMethod; 062 import org.apache.commons.httpclient.methods.HeadMethod; 063 import org.apache.commons.httpclient.methods.InputStreamRequestEntity; 064 import org.apache.commons.httpclient.methods.PostMethod; 065 import org.apache.commons.httpclient.methods.StringRequestEntity; 066 import org.deegree.enterprise.WebUtils; 067 import org.deegree.framework.log.ILogger; 068 import org.deegree.framework.log.LoggerFactory; 069 import org.deegree.framework.xml.XMLFragment; 070 071 /** 072 * utility class for performing HTTP requests 073 * 074 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 075 * @author last edited by: $Author: apoth $ 076 * 077 * @version. $Revision: 27357 $, $Date: 2010-10-18 18:06:09 +0200 (Mo, 18 Okt 2010) $ 078 */ 079 public class HttpUtils { 080 081 private static final ILogger LOG = LoggerFactory.getLogger( HttpUtils.class ); 082 083 /** 084 * validates passed URL. If it is not a valid URL or a client can not connect to it an exception will be thrown 085 * 086 * @param url 087 * @throws IOException 088 */ 089 public static int validateURL( String url ) 090 throws IOException { 091 return validateURL( url, null, null ); 092 } 093 094 /** 095 * validates passed URL. If it is not a valid URL or a client can not connect to it an exception will be thrown 096 * 097 * @param url 098 * @param user 099 * @param password 100 * @throws IOException 101 */ 102 public static int validateURL( String url, String user, String password ) 103 throws IOException { 104 if ( url.startsWith( "http:" ) ) { 105 URL tmp = new URL( url ); 106 HeadMethod hm = new HeadMethod( url ); 107 setHTTPCredentials( hm, user, password ); 108 InetAddress.getByName( tmp.getHost() ); 109 HttpClient client = new HttpClient(); 110 client.executeMethod( hm ); 111 if ( hm.getStatusCode() != HttpURLConnection.HTTP_OK ) { 112 if ( hm.getStatusCode() != HttpURLConnection.HTTP_UNAUTHORIZED && hm.getStatusCode() != 401 ) { 113 // this method just evaluates if a URL/host is valid; it does not takes care 114 // if authorization is available/valid 115 throw new IOException( "Host " + tmp.getHost() + " of URL + " + url + " does not exists" ); 116 } 117 } 118 return hm.getStatusCode(); 119 } else if ( url.startsWith( "file:" ) ) { 120 URL tmp = new URL( url ); 121 InputStream is = tmp.openStream(); 122 is.close(); 123 return 200; 124 } 125 return HttpURLConnection.HTTP_UNAVAILABLE; 126 } 127 128 /** 129 * 130 * @param url 131 * @param content 132 * @param timeout 133 * timeout in milliseconds 134 * @param user 135 * (can be <code>null</code>) 136 * @param password 137 * (can be <code>null</code>) 138 * @param contentType 139 * request content mime type (can be <code>null</code>) 140 * @param encoding 141 * request encoding (can be <code>null</code>) 142 * @param header 143 * 144 * @return result of http post request 145 * @throws HttpException 146 * @throws IOException 147 */ 148 public static HttpMethod performHttpPost( String url, InputStream content, int timeout, String user, 149 String password, String contentType, String encoding, 150 Map<String, String> header ) 151 throws HttpException, IOException { 152 HttpClient client = new HttpClient(); 153 URL tmp = new URL( url ); 154 WebUtils.enableProxyUsage( client, tmp ); 155 url = tmp.toExternalForm(); 156 client.getHttpConnectionManager().getParams().setSoTimeout( timeout ); 157 client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout ); 158 159 PostMethod pm = new PostMethod( url ); 160 String ct = contentType; 161 if ( ct != null && encoding != null ) { 162 ct += ( "; " + encoding ); 163 } 164 if ( ct != null ) { 165 pm.setRequestEntity( new InputStreamRequestEntity( content, ct ) ); 166 } else { 167 pm.setRequestEntity( new InputStreamRequestEntity( content ) ); 168 } 169 if ( header != null ) { 170 Iterator<String> iter = header.keySet().iterator(); 171 while ( iter.hasNext() ) { 172 String key = (String) iter.next(); 173 if ( !"content-length".equalsIgnoreCase( key ) ) { 174 pm.addRequestHeader( new Header( key, header.get( key ) ) ); 175 } 176 } 177 } 178 179 setHTTPCredentials( pm, user, password ); 180 client.executeMethod( pm ); 181 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { 182 LOG.logDebug( pm.getResponseBodyAsString() ); 183 } 184 if ( pm.getStatusCode() != 200 ) { 185 throw new HttpException( "status code: " + pm.getStatusCode() ); 186 } 187 return pm; 188 } 189 190 /** 191 * 192 * @param url 193 * @param content 194 * @param timeout 195 * timeout in milliseconds 196 * @param user 197 * (can <code>null</code>) 198 * @param password 199 * (can <code>null</code>) 200 * @param contentType 201 * request content mime type (can be <code>null</code>) 202 * @param encoding 203 * request encoding (can be <code>null</code>) 204 * @param header 205 * @return result of http post request 206 * @throws HttpException 207 * @throws IOException 208 */ 209 public static HttpMethod performHttpPost( String url, String content, int timeout, String user, String password, 210 String contentType, String encoding, Map<String, String> header ) 211 throws HttpException, IOException { 212 HttpClient client = new HttpClient(); 213 URL tmp = new URL( url ); 214 WebUtils.enableProxyUsage( client, tmp ); 215 url = tmp.toExternalForm(); 216 client.getHttpConnectionManager().getParams().setSoTimeout( timeout ); 217 client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout ); 218 PostMethod pm = new PostMethod( url ); 219 220 pm.setRequestEntity( new StringRequestEntity( content, contentType, encoding ) ); 221 222 if ( header != null ) { 223 Iterator<String> iter = header.keySet().iterator(); 224 while ( iter.hasNext() ) { 225 String key = (String) iter.next(); 226 if ( !"content-length".equalsIgnoreCase( key ) ) { 227 pm.addRequestHeader( new Header( key, header.get( key ) ) ); 228 } 229 } 230 } 231 pm.addRequestHeader( new Header( "content-length", Integer.toString( content.getBytes().length ) ) ); 232 233 setHTTPCredentials( pm, user, password ); 234 client.executeMethod( pm ); 235 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { 236 LOG.logDebug( pm.getResponseBodyAsString() ); 237 } 238 if ( pm.getStatusCode() != 200 ) { 239 throw new HttpException( "status code: " + pm.getStatusCode() ); 240 } 241 return pm; 242 } 243 244 /** 245 * 246 * @param url 247 * @param content 248 * @param timeout 249 * timeout in milliseconds 250 * @param user 251 * (can <code>null</code>) 252 * @param password 253 * (can <code>null</code>) 254 * @param header 255 * @return result of http post request 256 * @throws HttpException 257 * @throws IOException 258 */ 259 public static HttpMethod performHttpPost( String url, XMLFragment content, int timeout, String user, 260 String password, Map<String, String> header ) 261 throws HttpException, IOException { 262 HttpClient client = new HttpClient(); 263 URL tmp = new URL( url ); 264 WebUtils.enableProxyUsage( client, tmp ); 265 url = tmp.toExternalForm(); 266 client.getHttpConnectionManager().getParams().setSoTimeout( timeout ); 267 client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout ); 268 PostMethod pm = new PostMethod( url ); 269 270 ByteArrayOutputStream bos = new ByteArrayOutputStream( 1000000 ); 271 Properties props = new Properties(); 272 props.put( OutputKeys.ENCODING, "UTF-8" ); 273 content.write( bos, props ); 274 275 pm.setRequestEntity( new ByteArrayRequestEntity( bos.toByteArray(), "text/xml" ) ); 276 277 if ( header != null ) { 278 Iterator<String> iter = header.keySet().iterator(); 279 while ( iter.hasNext() ) { 280 String key = (String) iter.next(); 281 if ( !"content-length".equalsIgnoreCase( key ) ) { 282 pm.addRequestHeader( new Header( key, header.get( key ) ) ); 283 } 284 } 285 } 286 pm.addRequestHeader( new Header( "content-length", Integer.toString( bos.toByteArray().length ) ) ); 287 bos.close(); 288 289 setHTTPCredentials( pm, user, password ); 290 client.executeMethod( pm ); 291 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { 292 LOG.logDebug( pm.getResponseBodyAsString() ); 293 } 294 if ( pm.getStatusCode() != 200 ) { 295 throw new HttpException( "status code: " + pm.getStatusCode() ); 296 } 297 return pm; 298 } 299 300 /** 301 * 302 * @param url 303 * e.g. http://localhost:8080/deegree/services 304 * @param request 305 * e.g. service=WMS&request=GetCapabilities 306 * @param timeout 307 * timeout in milliseconds 308 * @param user 309 * (can be <code>null</code>) 310 * @param password 311 * (can be <code>null</code>) 312 * @param header 313 * @return result of http get request 314 * @throws HttpException 315 * @throws IOException 316 */ 317 public static HttpMethod performHttpGet( String url, String request, int timeout, String user, String password, 318 Map<String, String> header ) 319 throws HttpException, IOException { 320 if ( request != null && request.startsWith( "&" ) ) { 321 request = request.substring( 1 ); 322 } 323 if ( url != null && url.endsWith( "?" ) ) { 324 url = url.substring( 0, url.length() - 1 ); 325 } 326 LOG.logDebug( "HTTP GET URL: ", url ); 327 LOG.logDebug( "HTTP GET request: ", request ); 328 GetMethod gm = null; 329 if ( url.indexOf( '?' ) > -1 && request != null ) { 330 gm = new GetMethod( StringTools.concat( 500, url, '&', request ) ); 331 } else if ( request != null && !request.startsWith( "http://" ) ) { 332 gm = new GetMethod( StringTools.concat( 500, url, '?', request ) ); 333 } else if ( request != null && request.startsWith( "http://" ) ) { 334 gm = new GetMethod( request ); 335 } else { 336 gm = new GetMethod( url ); 337 } 338 339 if ( header != null ) { 340 Iterator<String> iter = header.keySet().iterator(); 341 while ( iter.hasNext() ) { 342 String key = (String) iter.next(); 343 if ( !"content-length".equalsIgnoreCase( key ) ) { 344 gm.addRequestHeader( new Header( key, header.get( key ) ) ); 345 } 346 347 } 348 } 349 350 setHTTPCredentials( gm, user, password ); 351 352 HttpClient client = new HttpClient(); 353 client.getHttpConnectionManager().getParams().setSoTimeout( timeout ); 354 client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout ); 355 WebUtils.enableProxyUsage( client, new URL( url ) ); 356 client.executeMethod( gm ); 357 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { 358 LOG.logDebug( gm.getResponseBodyAsString() ); 359 } 360 if ( gm.getStatusCode() != 200 ) { 361 throw new HttpException( "status code: " + gm.getStatusCode() ); 362 } 363 return gm; 364 } 365 366 /** 367 * 368 * @param url 369 * @param user 370 * @param password 371 * @param sessionID 372 * @return URL with attached authentication information (if not null) 373 */ 374 public static String addAuthenticationForKVP( String url, String user, String password, String sessionID ) { 375 if ( sessionID != null && sessionID.trim().length() > 0 ) { 376 url = url + "&sessionID=" + sessionID; 377 } else if ( user != null ) { 378 url = url + "&user=" + user; 379 if ( password == null ) { 380 password = ""; 381 } 382 url = url + "&password=" + password; 383 } 384 return url; 385 } 386 387 /** 388 * 389 * @param xml 390 * @param user 391 * @param password 392 * @param sessionID 393 * @return XML document with authentication information (if not null) as attributes of the root element 394 */ 395 public static XMLFragment addAuthenticationForXML( XMLFragment xml, String user, String password, String sessionID ) { 396 if ( sessionID != null ) { 397 xml.getRootElement().setAttribute( "sessionID", sessionID ); 398 } else if ( user != null ) { 399 xml.getRootElement().setAttribute( "user", user ); 400 if ( password != null ) { 401 xml.getRootElement().setAttribute( "password", password ); 402 } 403 } 404 return xml; 405 } 406 407 /** 408 * 409 * @param url 410 * @return URL as String with protocol and path but without request params 411 * @throws URISyntaxException 412 */ 413 public static String normalizeURL( URL url ) { 414 String pr = url.getProtocol(); 415 String ho = url.getHost(); 416 int po = url.getPort(); 417 String pa = url.getPath(); 418 String s = pr + "://" + ho + ':' + po; 419 if ( pa != null && pa.length() > 0 ) { 420 s += pa; 421 } 422 return s; 423 } 424 425 /** 426 * 427 * @param url 428 * @return URL as String with protocol and path but without request params 429 * @throws URISyntaxException 430 */ 431 public static String normalizeURL( String url ) { 432 try { 433 return normalizeURL( new URL( url ) ); 434 } catch ( MalformedURLException e ) { 435 LOG.logWarning( e.getMessage(), e ); 436 } 437 return url; 438 } 439 440 private static void setHTTPCredentials( HttpMethod m, String user, String password ) { 441 if ( user != null ) { 442 if ( password == null ) { 443 password = ""; 444 } 445 String s = new String( Base64.encodeBase64( ( user + ":" + password ).getBytes() ) ); 446 m.setRequestHeader( "authorization", "Basic " + s ); 447 } 448 } 449 450 }