001 //$HeadURL: http://svn.wald.intevation.org/svn/deegree/base/trunk/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: 30454 $, $Date: 2011-04-14 14:03:42 +0200 (Thu, 14 Apr 2011) $ 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 263 HttpClient client = new HttpClient(); 264 URL tmp = new URL( url ); 265 WebUtils.enableProxyUsage( client, tmp ); 266 url = tmp.toExternalForm(); 267 client.getHttpConnectionManager().getParams().setSoTimeout( timeout ); 268 client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout ); 269 PostMethod pm = new PostMethod( url ); 270 271 ByteArrayOutputStream bos = new ByteArrayOutputStream( 1000000 ); 272 Properties props = new Properties(); 273 props.put( OutputKeys.ENCODING, "UTF-8" ); 274 content.write( bos, props ); 275 276 pm.setRequestEntity( new ByteArrayRequestEntity( bos.toByteArray(), "text/xml" ) ); 277 278 if ( header != null ) { 279 Iterator<String> iter = header.keySet().iterator(); 280 while ( iter.hasNext() ) { 281 String key = (String) iter.next(); 282 if ( !"content-length".equalsIgnoreCase( key ) ) { 283 pm.addRequestHeader( new Header( key, header.get( key ) ) ); 284 } 285 } 286 } 287 pm.addRequestHeader( new Header( "content-length", Integer.toString( bos.toByteArray().length ) ) ); 288 bos.close(); 289 290 setHTTPCredentials( pm, user, password ); 291 client.executeMethod( pm ); 292 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { 293 LOG.logDebug( pm.getResponseBodyAsString() ); 294 } 295 if ( pm.getStatusCode() != 200 ) { 296 throw new HttpException( "status code: " + pm.getStatusCode() ); 297 } 298 return pm; 299 } 300 301 /** 302 * 303 * @param url 304 * e.g. http://localhost:8080/deegree/services 305 * @param request 306 * e.g. service=WMS&request=GetCapabilities 307 * @param timeout 308 * timeout in milliseconds 309 * @param user 310 * (can be <code>null</code>) 311 * @param password 312 * (can be <code>null</code>) 313 * @param header 314 * @return result of http get request 315 * @throws HttpException 316 * @throws IOException 317 */ 318 public static HttpMethod performHttpGet( String url, String request, int timeout, String user, String password, 319 Map<String, String> header ) 320 throws HttpException, IOException { 321 if ( request != null && request.startsWith( "&" ) ) { 322 request = request.substring( 1 ); 323 } 324 if ( url != null && url.endsWith( "?" ) ) { 325 url = url.substring( 0, url.length() - 1 ); 326 } 327 LOG.logDebug( "HTTP GET URL: ", url ); 328 LOG.logDebug( "HTTP GET request: ", request ); 329 GetMethod gm = null; 330 if ( url.indexOf( '?' ) > -1 && request != null ) { 331 gm = new GetMethod( StringTools.concat( 500, url, '&', request ) ); 332 } else if ( request != null && !request.startsWith( "http://" ) ) { 333 gm = new GetMethod( StringTools.concat( 500, url, '?', request ) ); 334 } else if ( request != null && request.startsWith( "http://" ) ) { 335 gm = new GetMethod( request ); 336 } else { 337 gm = new GetMethod( url ); 338 } 339 340 if ( header != null ) { 341 Iterator<String> iter = header.keySet().iterator(); 342 while ( iter.hasNext() ) { 343 String key = (String) iter.next(); 344 if ( !"content-length".equalsIgnoreCase( key ) ) { 345 gm.addRequestHeader( new Header( key, header.get( key ) ) ); 346 } 347 348 } 349 } 350 351 setHTTPCredentials( gm, user, password ); 352 353 HttpClient client = new HttpClient(); 354 client.getHttpConnectionManager().getParams().setSoTimeout( timeout ); 355 client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout ); 356 WebUtils.enableProxyUsage( client, new URL( url ) ); 357 client.executeMethod( gm ); 358 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { 359 LOG.logDebug( gm.getResponseBodyAsString() ); 360 } 361 if ( gm.getStatusCode() != 200 ) { 362 throw new HttpException( "status code: " + gm.getStatusCode() ); 363 } 364 return gm; 365 } 366 367 /** 368 * 369 * @param url 370 * @param user 371 * @param password 372 * @param sessionID 373 * @return URL with attached authentication information (if not null) 374 */ 375 public static String addAuthenticationForKVP( String url, String user, String password, String sessionID ) { 376 if ( sessionID != null && sessionID.trim().length() > 0 ) { 377 url = url + "&sessionID=" + sessionID; 378 } else if ( user != null ) { 379 url = url + "&user=" + user; 380 if ( password == null ) { 381 password = ""; 382 } 383 url = url + "&password=" + password; 384 } 385 return url; 386 } 387 388 /** 389 * 390 * @param xml 391 * @param user 392 * @param password 393 * @param sessionID 394 * @return XML document with authentication information (if not null) as attributes of the root element 395 */ 396 public static XMLFragment addAuthenticationForXML( XMLFragment xml, String user, String password, String sessionID ) { 397 if ( sessionID != null ) { 398 xml.getRootElement().setAttribute( "sessionID", sessionID ); 399 } else if ( user != null ) { 400 xml.getRootElement().setAttribute( "user", user ); 401 if ( password != null ) { 402 xml.getRootElement().setAttribute( "password", password ); 403 } 404 } 405 return xml; 406 } 407 408 /** 409 * 410 * @param url 411 * @return URL as String with protocol and path but without request params 412 * @throws URISyntaxException 413 */ 414 public static String normalizeURL( URL url ) { 415 String pr = url.getProtocol(); 416 String ho = url.getHost(); 417 int po = url.getPort(); 418 String pa = url.getPath(); 419 String s = pr + "://" + ho + ':' + po; 420 if ( pa != null && pa.length() > 0 ) { 421 s += pa; 422 } 423 return s; 424 } 425 426 /** 427 * 428 * @param url 429 * @return URL as String with protocol and path but without request params 430 * @throws URISyntaxException 431 */ 432 public static String normalizeURL( String url ) { 433 try { 434 return normalizeURL( new URL( url ) ); 435 } catch ( MalformedURLException e ) { 436 LOG.logWarning( e.getMessage(), e ); 437 } 438 return url; 439 } 440 441 private static void setHTTPCredentials( HttpMethod m, String user, String password ) { 442 if ( user != null ) { 443 if ( password == null ) { 444 password = ""; 445 } 446 String s = new String( Base64.encodeBase64( ( user + ":" + password ).getBytes() ) ); 447 m.setRequestHeader( "authorization", "Basic " + s ); 448 } 449 } 450 451 }